We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexDiscussionExhibition › Using graphics tablet with JPen
Page Index Toggle Pages: 1
Using graphics tablet with JPen (Read 2957 times)
Using graphics tablet with JPen
Sep 5th, 2009, 9:53am
 
I wanted to get a graphics tablet for years, but it was too expensive. Last year I finally made the investment. I bought a Wacom Bamboo in A5 format. Not as precise and feature full as an Intuos, but nice to play with anyway.
Naturally, I looked if I could use it within Processing. I looked at JTablet, but it seemed a bit outdated and problematic. I saw a reference to JPen and tried it. It had a pair standalone demos, one just dumping lot of textual data about pen manipulation, another quite impressive, given it simplicity, allowing to do simple draws with pressure effects.
I took the source code of the latter, and adapted it to Processing. But at the time, it was Java 1.5 (IIRC), and JPen was 1.6. I tried to recompile it, without success. I went to other things.

Recently, I tried again, with the latest version of Processing and of JPen, and it worked out of the box! And Jpen supports MacOS X now. Some minor code fixes, some uses of the new features, and here is the demo code:
Code:
import jpen.event.*;
import jpen.*;

void setup()
{
 size(800, 800);

 PenManager pm = new PenManager(this);
 pm.pen.addListener(new ProcessingPen());
 smooth();
 background(#FFFFFF);
}

void draw()
{
}

// Most of the code here is taken from the DrawingSurface demo code.
public class ProcessingPen extends PenAdapter
{
 boolean bIsDown;
 float prevXPos = -1, prevYPos = -1;

 public void penButtonEvent(PButtonEvent evt)
 {
   // See if the pen is down
   bIsDown = evt.pen.hasPressedButtons();
   /* Or check with a finer granularity.
   // Pen pressed is LEFT for me (Bamboo).
   if (evt.pen.getButtonValue(PButton.Type.LEFT))
println("LEFT");
   if (evt.pen.getButtonValue(PButton.Type.CENTER))
println("CENTER");
   // Pen button pressed is RIGHT
   if (evt.pen.getButtonValue(PButton.Type.RIGHT))
println("RIGHT");
   //*/
 }

 public void penLevelEvent(PLevelEvent evt)
 {
   // Get kind of event: does it come from mouse (CURSOR), STYLUS or ERASER?
   PKind type = evt.pen.getKind();
   // Discard events from mouse
   if (type == PKind.valueOf(PKind.Type.CURSOR))
return;

   // Get the current cursor location
   float xPos = evt.pen.getLevelValue(PLevel.Type.X);
   float yPos = evt.pen.getLevelValue(PLevel.Type.Y);

   // Set the brush's size, and darkness relative to the pressure
   float pressure = evt.pen.getLevelValue(PLevel.Type.PRESSURE);
   float brushSize = pressure * 10;
   float darkness = 255 * pressure;

   // Get the tilt values (not with a Bamboo... so untested!)
   float xTilt = evt.pen.getLevelValue(PLevel.Type.TILT_X);
   float yTilt = evt.pen.getLevelValue(PLevel.Type.TILT_Y);
   // Transform them to azimuthX and altitude, two angles with the projection of the pen against the X-Y plane
   // azimuthX is the angle (clockwise direction) between this projection and the X axis. Range: -pi/2 to 3*pi/2.
   // altitude is the angle between this projection and the pen itself. Range: 0 to pi/2.
   // Might be more pratical to use than raw x/y tilt values.
   double[] aa = { 0.0, 0.0 };
   PLevel.Type.evalAzimuthXAndAltitude(aa, xTilt, yTilt);
   // or just PLevel.Type.evalAzimuthXAndAltitude(aa, evt.pen);
   double azimuthX = aa[0];
   double altitude = aa[1];

   /* If the stylus is being pressed down, we want to draw a black
line onto the screen. If it's the eraser, we want to create
a white line, effectively "erasing" the black line
   */
   if (type == PKind.valueOf(PKind.Type.STYLUS))
   {
color c = color(0, 0, 255 - darkness);
stroke(c);
   }
   else if (type == PKind.valueOf(PKind.Type.ERASER))
   {
stroke(255, darkness);
   }
   else
   {
return; // IGNORE or CUSTOM...
   }

   if (!evt.isMovement())
   {
// Not a movement, just draw a dot
ellipse(xPos, yPos, brushSize, brushSize);
return;
   }

   if (!bIsDown)
   {
// Pen up, stop current line and down't draw anywthing
prevXPos = -1;
return;
   }

   if (prevXPos == -1)
   {
prevXPos = xPos;
prevYPos = yPos;
   }

   // Draw a line between the current and previous locations
   strokeWeight(brushSize);
   line(prevXPos, prevYPos, xPos, yPos);
   prevXPos = xPos;
   prevYPos = yPos;
 }

 // When user moves on the big round scroll button
 void penScrollEvent(PScrollEvent evt)
 {
   PScroll.Type type = evt.scroll.getType();
   int value = evt.scroll.value;
   if (type == PScroll.Type.DOWN)
   {
println("Scrolling down " + value);
   }
   else if (type == PScroll.Type.UP)
   {
println("Scrolling up " + value);
   }
   else if (type == PScroll.Type.CUSTOM)
   {
println("Scrolling custom (?) " + value);
   }
 }

 // What is it?
 void penKindEvent(PScrollEvent evt)
 {
   println("Kind Event: " + evt);
 }
}

OK, it will be useless for most of you, but those fortunate enough to own such device, I hope this code might be a good starting point.

PS.: 'ac' wrapped JPen in a library for Processing, you might be interested by it instead of using raw library.
Re: Using graphics tablet with JPen
Reply #1 - Sep 22nd, 2009, 8:59pm
 
Hi Phil_ho,

thanks for your post. I've been thinking about how I could use a graphics tablet with Processing. I will have to give it a try.

I've been thinking about creating a sketch to help my kids practice handwriting. Something like getting them to copy letters and giving them a score or feedback depending on how close they are.
Re: Using graphics tablet with JPen
Reply #2 - Dec 7th, 2009, 9:28pm
 
I have been researching using graphic tablets with Processing. @forestgarden did you try it out How did it work for you
Re: Using graphics tablet with JPen
Reply #3 - Dec 9th, 2009, 11:03am
 
Thanks for posting this. I have a Wacom Intuos 3 tablet that I love using, and had been thinking about getting it going in Processing. I tried downloading the JPen library and installing it, but I think I might be putting it in the wrong place..... do I download the library you provided a link to....and where do I put the files?
Re: Using graphics tablet with JPen
Reply #4 - Dec 9th, 2009, 12:48pm
 
A simple way to use it in a sketch is to drag'n'drop the jar file on the PDE window. It will put it in the sketch's folder under the 'code' sub-folder.
Re: Using graphics tablet with JPen
Reply #5 - Dec 9th, 2009, 1:04pm
 
I did that, and now I get this error (with your program).

9/12/2009 4:00:36 PM jpen.provider.NativeLibraryLoader$4 run
INFO: loading JNI library: jpen-2 ...
9/12/2009 4:00:36 PM jpen.provider.NativeLibraryLoader$4 logOnFail
INFO: jpen-2 couldn't be loaded
9/12/2009 4:00:36 PM jpen.provider.NativeLibraryLoader load
INFO: no suitable JNI library found
Re: Using graphics tablet with JPen
Reply #6 - Dec 10th, 2009, 4:34am
 
Oh, yes, I forgot, you have to put the jpen-2.dll along with the jpen-2.jar file in the code folder. Sorry.
Re: Using graphics tablet with JPen
Reply #7 - Dec 10th, 2009, 6:55am
 
OK...did that, and it now works perfectly. Fantastic! This is going to open up some great possibilities for interactivity making use of the pressure sensitivity...and other things. Thanks again for posting!
Re: Using graphics tablet with JPen
Reply #8 - Dec 14th, 2009, 12:02pm
 
Thanks a lot. I am using the wrapped JPen library for Processing now on Mac OSX with my Wacom Intuos 3 tablet and it works great! This deserves a place in the Processing libraries section on the website! Why isn't it there?
Page Index Toggle Pages: 1