Penlets.com provides resources for users and developers of the Pulse smart pen from LiveScribe.
Subscribe: RSS Feed - Developers Group
Tutorial
Loading and Displaying an Image
Tutorial by Robert HansonIn this tutorial we are going to explain how to display an image in the OLED display of the Pulse pen. Thankfully, this is a simple task. If you plan on following along and coding this as we go, now is the time to break out your IDE and create a new project.
As usual, we begin with our base application. We need to import the
usual Penlet, Display, and ScrollLabel
classes along with a few specific to this tutorial. The standard Java
InputStream and IOException
classes will be utilized in reading the image from the pen so that we
can display it. When we load the image, we will store it as an object
of type Image, a class specific to the LiveScribe API.
package com.penlets.graphics;
import java.io.IOException;
import java.io.InputStream;
import com.livescribe.display.Display;
import com.livescribe.display.Image;
import com.livescribe.penlet.Penlet;
import com.livescribe.penlet.PenletStateChangeException;
import com.livescribe.ui.ScrollLabel;
public class ImageDemo extends Penlet
{
private Display display;
private ScrollLabel label;
public void initApp () throws PenletStateChangeException
{
this.display = this.context.getDisplay();
this.label = new ScrollLabel();
}
public void activateApp (int reason, Object[] args)
{
this.display.setCurrent(label);
}
public void deactivateApp (int reason) { }
public void destroyApp () throws PenletStateChangeException { }
}
You may have noticed that in the
activateApp()
method we add our
ScrollLabel()
to the pen's display, but we didn't draw anything in it. So that is
what we need to do next. To promote reuse we create a new method
loadImage()
, which takes a path argument, and call it in
initApp()
. Note that the path is an absolute path starting with "/images/".
This is required if you want the build scripts that came with the SDK
to save you some work. We will explain all of this in a minute.
With an
Image
object in hand we call
draw()
on the
ScrollLabel
with three arguments. The first is the image that we want displayed.
The second argument is the text that we want displayed, but because
we don't actually want any text displayed we pass a null value. The
third argument is a flag indicating if we want the
ScrollLabel
to scroll the display. This can be set to true if your image is wider
than the 98 pixel display width, but here we set it to false, no
scrolling.
public void initApp () throws PenletStateChangeException
{
this.display = this.context.getDisplay();
this.label = new ScrollLabel();
Image image = loadImage("/images/penlets.arw");
this.label.draw(image, null, false);
}
private Image loadImage (String imagePath)
{
return null; // TO-DO
}
In the code listing we referenced the image "/images/penlets.arw",
but we didn't tell you where that came from yet, and what an "arw"
file is. In your standard project setup you will have a folder
/res
in your project. Under this directory you need to create an images
directory, the path withing the project being
/res/images/
. You need to place all of your TIFF and BMP files. When you run the
deploy the application to the pen using the ant task supplied with
the SDK it will convert all of these files into ARW files and place
them in the JAR that is created.
Details for image development The viewable area of the Pulse display is 98 pixels wide by 18 pixels high. The image files must have an extension of "tiff" (two-"f"s) or "bmp", and they must be lower-case. All other extensions are ignored for the purpose of converting them to "arw". Images must be black-and-white, grayscale will not work. Items shown in the pen's display are typically white on a black background, your images will likely be the same unless you want a "negative" look.
There is one small but important caveat when adding images to your project. The images must be only black and white, so be sure to set this in your image editor. Most image editors will either have an explicit black/white mode, or an indexed color mode that allows you to specify a 1 bit color depth. Do not confuse this with "grayscale", which will not work.
Using Gimp Set the correct mode under Tools > Mode on the menu bar, and select "Indexed". This will launch a dialog box, in which you need to select "Use black and white (1-bit) palette". Using MS Paint Set the correct mode under Image > Attributes on the menu bar, and select "Black and white".
The last piece of the puzzle is to implement the
loadImage()
method. Unfortunately the code is a bit verbose due to the nature of
Java's overuse of I/O exceptions as we can see below.
private Image loadImage (String imagePath)
{
Image image = null;
InputStream stream = getClass().getResourceAsStream(imagePath);
try {
image = Image.createImage(stream);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (stream != null) {
try {
stream.close();
}
catch (IOException e) { }
stream = null;
}
}
return image;
}
The only code of real importance is the call to
getClass().getResourceAsStream()
, which returns an handle from which the image file can be read, and
Image.createImage()
, which reads the image data from the stream and creates the
Image
object. The rest of it is just to handle any exception that might be
thrown, and ensure that the data stream is properly closed.
If you followed along with us you should now have an application that can be deployed to the pen, and an image should be displayed. If things didn't go right, double check that the image is set to indexed color and that it is properly named. If that doesn't help, try adding some logging to the code to help isolate the problem.
Good luck, and happy coding.
Comments (View) blog comments powered by DisqusProject Information
Tested for use with: JaveOne-SDK
Download the source code for this tutorial.
Download Source Code (zip)
New Tutorials
Using a Shared Library
Learn how to create a library of utils that you can
share between projects.
Capturing Drawn Shapes
Learn how to capture shapes drawn by the pen and determine relationships.
Penlets 101
Never written a penlet before? Then start here with Penlets 101!
Creating a Custom Vocabulary
Learn how to create a custom vocabulary for your ICR applications.
Using Properties Files
J2ME lacks a Properties class. In this tutorial we roll our own,
along with split and chomp functions.