image api changes for blend, save, parent object control

This commit is contained in:
benfry
2006-09-24 21:51:02 +00:00
parent 902e20bca3
commit 39196d26a0
12 changed files with 446 additions and 357 deletions
+42 -2
View File
@@ -9,17 +9,57 @@ releases will be super crusty.
ABOUT REV 0116 - ?? ?? 2006
+ the flag in PApplet.main() formerly called --present-stop-color
This is a major release. It contains a large number of bug fixes,
as well as several API changes as we try to firm up the API for 1.0.
*** PLEASE READ ALL THESE NOTES CAREFULLY ***
+ Threading has been modified signficantly.
+ The OpenGL library has been updated to use the "final" release
of JOGL 1.0, released September 2006, rather than beta 4, found
in release 0115.
+ The flag in PApplet.main() formerly called --present-stop-color
is now simply --stop-color. A flag named --hide-stop has also
been added, to prevent users from quitting out of a present mode
application. see the faq on details for capturing ESC as well.
+ altered mouse behavior so that mouse positions update only on
+ Altered mouse behavior so that mouse positions update only on
mouseMoved and mouseDragged. this also fixes a macosx bug that
caused mouseX/Y values to be bizarre because mouseExited()
gave weird positions (workaround for apple bug).
[ Major changes to the use of PGraphics and its subclasses ]
+ The PGraphics classes have all been reworked and renamed.
- PGraphics is an abstract class on which additional PGraphics
subclasses can be built. It is an abstract class, and therefore
cannot be invoked directly.
- PGraphics2D (P2D) contains the former contents of PGraphics that
are specific to 2D rendering. This will be P2D once it is complete.
- PGraphics3D (P3D), formerly PGraphics3, remains mostly unchanged.
- PGraphicsJava2D (JAVA2D), formerly PGraphics2, is the renderer
used when you call for size(width, height, JAVA2D). It remains
the default renderer when none is specified. It is slower but
more accurate than the others.
+ Do not use new PGraphics(...) to create PGraphics objects.
Instead, use createGraphics(), which will properly handle connecting
the new graphics object to its parent sketch, and will enable save()
to work properly. See the reference for createGraphics:
http://processing.org/reference/createGraphics_.html
+ For the same reasons as above, createImage(width, height, format)
should be used instead of new PImage(...) when creating images:
http://test.processing.org/reference/createImage_.html
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+220 -116
View File
@@ -38,6 +38,78 @@ import java.util.zip.*;
/**
* Base class for all sketches that use processing.core.
* <p/>
* Note that you should not use AWT or Swing components inside a Processing
* applet. The surface is made to automatically update itself, and will cause
* problems with redraw of components drawn above it. If you'd like to
* integrate other Java components, see below.
* <p/>
* This class extends Applet instead of JApplet because 1) we will eventually
* be returning Java 1.1 support, which does not include Swing (without an
* additional, sizable, download), and 2) Swing is a bloated piece of crap.
* A Processing applet is a heavyweight AWT component, and can be used the
* same as any other AWT component.
* <p/>
* Similarly, Processing runs in a Frame and not a JFrame. However, there's
* nothing to prevent you from embedding a PApplet into a JFrame, it's just
* that the base version uses a regular AWT frame because there's simply
* no need for swing in that context. If people want to use Swing, they can
* embed themselves as they wish.
* <p/>
* It is possible to use PApplet, along with core.jar in other projects.
* In addition to enabling you to use Java 1.5+ features with your sketch,
* this also allows you to embed a Processing drawing area into another Java
* application. This means you can use standard GUI controls with a Processing
* sketch. Because AWT and Swing GUI components cannot be used on top of a
* PApplet, you can instead embed the Component inside another GUI the way
* you would any other Component.
* <p/>
* By default, the animation thread will run at 60 frames per second,
* which can make the parent applet sluggish. If you want to only update the
* sketch intermittently, use noLoop() inside setup(), and redraw() whenever
* the screen needs to be updated once, or loop() to re-enable the animation
* thread. The following example embeds a sketch and also uses the noLoop()
* and redraw() methods. You need not use noLoop() and redraw() when embedding
* if you want your application to animate continuously.
* <PRE>
* public class ExampleFrame extends Frame {
*
* public ExampleFrame() {
* super("Embedded PApplet");
*
* setLayout(new BorderLayout());
* PApplet embed = new Embedded();
* add(embed, BorderLayout.CENTER);
*
* // important to call this whenever embedding a PApplet.
* // It ensures that the animation thread is started and
* // that other internal variables are properly set.
* embed.init();
* }
* }
*
* public class Embedded extends PApplet {
*
* public void setup() {
* // original setup code here ...
* size(400, 400);
*
* // prevent thread from starving everything else
* noLoop();
* }
*
* public void draw() {
* // drawing code goes here
* }
*
* public void mousePressed() {
* // do something based on mouse movement
*
* // update the screen (run draw once)
* redraw();
* }
* }
* </PRE>
*/
public class PApplet extends Applet
implements PConstants, Runnable,
@@ -797,6 +869,7 @@ public class PApplet extends Applet
// otherwise ok to fall through and create renderer below
// the renderer is changing, so need to create a new object
g = createGraphics(iwidth, iheight, irenderer, ipath);
g.setMainDrawingSurface();
//if (g != null) {
updateSize(iwidth, iheight);
//}
@@ -809,6 +882,7 @@ public class PApplet extends Applet
}
} else { // none exists, just create a freshy
g = createGraphics(iwidth, iheight, irenderer, ipath);
g.setMainDrawingSurface();
updateSize(iwidth, iheight);
}
@@ -864,6 +938,9 @@ public class PApplet extends Applet
/*
// these constructors removed because they were silly
public PGraphics createGraphics(String renderer) {
return createGraphics(width, height, renderer);
}
@@ -872,29 +949,29 @@ public class PApplet extends Applet
public PGraphics createGraphics(int iwidth, int iheight) {
return createGraphics(iwidth, iheight, g.getClass().getName());
}
*/
public PGraphics createGraphics(String irenderer, String ipath) {
return createGraphics(width, height, irenderer, this, ipath);
}
*/
public PGraphics createGraphics(int iwidth, int iheight,
String irenderer) {
return createGraphics(iwidth, iheight, irenderer, this, null);
return createGraphics(iwidth, iheight, irenderer, null, this);
}
public PGraphics createGraphics(int iwidth, int iheight,
String irenderer, String ipath) {
return createGraphics(iwidth, iheight, irenderer, this, ipath);
return createGraphics(iwidth, iheight, irenderer, ipath, this);
}
static public PGraphics createGraphics(int iwidth, int iheight,
String irenderer, PApplet applet,
String ipath) {
String irenderer, String ipath,
PApplet applet) {
/*
// ok when calling size, but not really with createGraphics()
if (renderer.equals(OPENGL)) {
@@ -933,9 +1010,8 @@ public class PApplet extends Applet
Constructor constructor =
rendererClass.getConstructor(constructorParams);
// create the actual PGraphics object for rendering
return (PGraphics) constructor.newInstance(constructorValues);
//updateSize(iwidth, iheight);
PGraphics pg = (PGraphics) constructor.newInstance(constructorValues);
return pg;
} catch (InvocationTargetException ite) {
String msg = ite.getTargetException().getMessage();
@@ -977,28 +1053,23 @@ public class PApplet extends Applet
} else {
if (platform == MACOSX) e.printStackTrace(System.out);
//System.err.flush();
//return null;
throw new RuntimeException(e.getMessage());
//die("Could not create " + irenderer);
}
/*
} catch (Exception e) {
e.printStackTrace();
die("Could not start because of a problem with size()", e);
*/
}
// clear things out to get started
//outgoing.defaults();
// tell people to use beginDraw/endDraw
// and send 'em off
//return outgoing;
}
/**
* Preferred method of creating new PImage objects, ensures that a
* reference to the parent PApplet is included, which makes save() work
* without needing an absolute path.
*/
public PImage createImage(int width, int height, int format) {
PImage image = new PImage(width, height, format);
image.parent = this; // make save() work
return image;
}
public void update(Graphics screen) {
//System.out.println("PApplet.update()");
if (THREAD_DEBUG) println(Thread.currentThread().getName() +
@@ -2280,9 +2351,9 @@ public class PApplet extends Applet
//
int cursor_type = ARROW; // cursor type
boolean cursor_visible = true; // cursor visibility flag
PImage invisible_cursor;
int cursorType = ARROW; // cursor type
boolean cursorVisible = true; // cursor visibility flag
PImage invisibleCursor;
/**
@@ -2290,8 +2361,8 @@ public class PApplet extends Applet
*/
public void cursor(int _cursor_type) {
setCursor(Cursor.getPredefinedCursor(_cursor_type));
cursor_visible = true;
cursor_type = _cursor_type;
cursorVisible = true;
cursorType = _cursor_type;
}
@@ -2330,7 +2401,7 @@ public class PApplet extends Applet
hotspot,
"no cursor" });
setCursor(cursor);
cursor_visible = true;
cursorVisible = true;
} catch (NoSuchMethodError e) {
System.err.println("cursor() is not available " +
@@ -2353,9 +2424,9 @@ public class PApplet extends Applet
// it's likely that java will set the cursor to something
// else on its own, and the applet will be stuck b/c bagel
// thinks that the cursor is set to one particular thing
if (!cursor_visible) {
cursor_visible = true;
setCursor(Cursor.getPredefinedCursor(cursor_type));
if (!cursorVisible) {
cursorVisible = true;
setCursor(Cursor.getPredefinedCursor(cursorType));
}
}
@@ -2365,15 +2436,15 @@ public class PApplet extends Applet
* and using it as a custom cursor.
*/
public void noCursor() {
if (!cursor_visible) return; // don't hide if already hidden.
if (!cursorVisible) return; // don't hide if already hidden.
if (invisible_cursor == null) {
invisible_cursor = new PImage(16, 16, ARGB);
if (invisibleCursor == null) {
invisibleCursor = new PImage(16, 16, ARGB);
}
// was formerly 16x16, but the 0x0 was added by jdf as a fix
// for macosx, which didn't wasn't honoring the invisible cursor
cursor(invisible_cursor, 0, 0);
cursor_visible = false;
cursor(invisibleCursor, 0, 0);
cursorVisible = false;
}
@@ -3107,14 +3178,88 @@ public class PApplet extends Applet
* work that will be posted on the web. To get a list of possible
* image formats for use with Java 1.4 and later, use the following:
* <TT>println(javax.imageio.ImageIO.getReaderFormatNames())</TT>
* <P>
* Images are loaded via a byte array that is passed to
* Toolkit.createImage(). Unfortunately, we cannot use Applet.getImage()
* because it takes a URL argument, which would be a pain in the a--
* to make work consistently for online and local sketches.
* Sometimes this causes problems, resulting in issues like
* <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=279">Bug 279</A>
* and
* <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=305">Bug 305</A>.
* In release 0115, everything was instead run through javax.imageio,
* but that turned out to be very slow, see
* <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=392">Bug 392</A>.
* As a result, starting with 0116, the following happens:
* <UL>
* <LI>TGA and TIFF images are loaded using the internal load methods.
* <LI>JPG, GIF, and PNG images are loaded via loadBytes().
* <LI>If the image still isn't loaded, it's passed to javax.imageio.
* </UL>
* For releases 0116 and later, if you have problems such as those seen
* in Bugs 279 and 305, use Applet.getImage() instead. You'll be stuck
* with the limitations of getImage() (the headache of dealing with
* online/offline use). Set up your own MediaTracker, and pass the resulting
* java.awt.Image to the PImage constructor that takes an AWT image.
* You can also use the loadImageSync() function (added in 0116) that
* takes an AWT image and loads it synchronously inside PApplet.
* This isn't much fun, but this will have to do unless we find the
* actual culprit, which may still be a threading issue.
* <PRE>
* public PImage loadImageAlt(String filename) {
* java.awt.Image img = getImage(getCodeBase(), filename);
* return loadImageSync(img);
* }
* </PRE>
*/
public PImage loadImage(String filename) {
// it's not clear whether this method is more efficient for
// loading gif, jpeg, and png data than the standard toolkit function,
// in fact it may even be identical. but who knows, with any luck
// it may even fix the image loading problems from bug #279.
// http://dev.processing.org/bugs/show_bug.cgi?id=279
// (if anyone reading this knows for certain, please post)
String lower = filename.toLowerCase();
if (lower.endsWith(".tga")) {
try {
return loadImageTGA(filename);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
if (lower.endsWith(".tif") || lower.endsWith(".tiff")) {
byte bytes[] = loadBytes(filename);
return (bytes == null) ? null : PImage.loadTIFF(bytes);
}
// Make sure that PNG images aren't being loaded by Java 1.1
if (lower.endsWith(".png") && PApplet.javaVersion < 1.3f) {
System.err.println("PNG images can only be loaded when " +
"using Java 1.3 and later.");
return null;
}
// For jpeg, gif, and png, load them using createImage(),
// because the javax.imageio code was found to be much slower, see
// <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=392">Bug 392</A>.
try {
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg") ||
lower.endsWith(".gif") || lower.endsWith(".png")) {
byte bytes[] = loadBytes(filename);
if (bytes == null) {
return null;
} else {
Image awtImage = Toolkit.getDefaultToolkit().createImage(bytes);
PImage image = loadImageSync(awtImage);
// if it's a .gif image, test to see if it has transparency
if ((lower.endsWith(".gif")) || (lower.endsWith(".png"))) {
image.checkAlpha();
}
return image;
}
}
} catch (Exception e) {
// show error, but move on to the stuff below, see if it'll work
e.printStackTrace();
}
if (PApplet.javaVersion >= 1.4f) {
if (loadImageFormats == null) {
//loadImageFormats = javax.imageio.ImageIO.getReaderFormatNames();
@@ -3137,42 +3282,25 @@ public class PApplet extends Applet
}
}
if (filename.toLowerCase().endsWith(".tga")) {
try {
return loadImageTGA(filename);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
// failed, could not load image after all those attempts
return null;
}
byte bytes[] = loadBytes(filename);
if (bytes == null) return null;
if (filename.toLowerCase().endsWith(".tif") ||
filename.toLowerCase().endsWith(".tiff")) {
return PImage.loadTIFF(bytes);
}
Image awtImage = Toolkit.getDefaultToolkit().createImage(bytes);
/**
* Load an AWT image synchronously.
*/
public PImage loadImageSync(Image awtImage) {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(awtImage, 0);
try {
tracker.waitForAll();
} catch (InterruptedException e) {
// don't bother, since this may be interrupted by draw
// or noLoop or something like that
//e.printStackTrace(); // non-fatal, right?
}
PImage image = new PImage(awtImage);
// if it's a .gif image, test to see if it has transparency
if ((filename.toLowerCase().endsWith(".gif")) ||
(filename.toLowerCase().endsWith(".png"))) {
image.checkAlpha();
}
image.parent = this;
return image;
}
@@ -3216,6 +3344,7 @@ public class PApplet extends Applet
// with the old method.
PImage outgoing = new PImage(wi.intValue(), hi.intValue());
outgoing.parent = this;
Method getRgbMethod =
biClass.getMethod("getRGB", new Class[] {
@@ -3283,6 +3412,7 @@ public class PApplet extends Applet
int w = ((header[13] & 0xff) << 8) + (header[12] & 0xff);
int h = ((header[15] & 0xff) << 8) + (header[14] & 0xff);
PImage outgoing = new PImage(w, h, format);
outgoing.parent = this;
int index = 0;
int px[] = outgoing.pixels;
@@ -3337,31 +3467,7 @@ public class PApplet extends Applet
}
}
return outgoing;
/*
// targa's are written upside down, so we need to parse it in reverse
int index = (h-1) * w;
// actual bitmap data starts at byte 18
int offset = 18;
// read out line by line
for (int y = h-1; y >= 0; y--) {
for (int x = 0; x < w; x++) {
img.pixels[index + x] =
(buffer[offset++] & 0xff) |
((buffer[offset++] & 0xff) << 8) |
((buffer[offset++] & 0xff) << 16) |
(hasAlpha ? ((buffer[offset++] & 0xff) << 24) : 0xff000000);
}
index -= w;
}
return img;
}
System.err.println("loadImage(): bad targa image format");
return null;
*/
}
}
@@ -3621,14 +3727,14 @@ public class PApplet extends Applet
* I want to read lines from a file. I have RSI from typing these
* eight lines of code so many times.
*/
public BufferedReader reader(String filename) {
public BufferedReader createReader(String filename) {
try {
InputStream is = openStream(filename);
if (is == null) {
System.err.println(filename + " does not exist or could not be read");
return null;
}
return reader(is);
return createReader(is);
} catch (Exception e) {
if (filename == null) {
@@ -3644,9 +3750,9 @@ public class PApplet extends Applet
/**
* I want to read lines from a file. And I'm still annoyed.
*/
static public BufferedReader reader(File file) {
static public BufferedReader createReader(File file) {
try {
return reader(new FileInputStream(file));
return createReader(new FileInputStream(file));
} catch (Exception e) {
if (file == null) {
@@ -3665,7 +3771,7 @@ public class PApplet extends Applet
* I want to read lines from a stream. If I have to type the
* following lines any more I'm gonna send Sun my medical bills.
*/
static public BufferedReader reader(InputStream input) {
static public BufferedReader createReader(InputStream input) {
InputStreamReader isr = new InputStreamReader(input);
return new BufferedReader(isr);
}
@@ -3702,9 +3808,9 @@ public class PApplet extends Applet
/**
* I want to print lines to a file. Why can't I?
*/
public PrintWriter writer(String filename) {
public PrintWriter createWriter(String filename) {
try {
return writer(new FileOutputStream(savePath(filename)));
return createWriter(new FileOutputStream(savePath(filename)));
} catch (Exception e) {
if (filename == null) {
@@ -3721,9 +3827,9 @@ public class PApplet extends Applet
* I want to print lines to a file. I have RSI from typing these
* eight lines of code so many times.
*/
static public PrintWriter writer(File file) {
static public PrintWriter createWriter(File file) {
try {
return writer(new FileOutputStream(file));
return createWriter(new FileOutputStream(file));
} catch (Exception e) {
if (file == null) {
@@ -3742,7 +3848,7 @@ public class PApplet extends Applet
* I want to print lines to a file. Why am I always explaining myself?
* It's the JavaSoft API engineers who need to explain themselves.
*/
static public PrintWriter writer(OutputStream output) {
static public PrintWriter createWriter(OutputStream output) {
OutputStreamWriter osw = new OutputStreamWriter(output);
return new PrintWriter(osw);
}
@@ -6542,21 +6648,13 @@ public class PApplet extends Applet
}
static public int blend(int c1, int c2, int mode) {
return PGraphics.blend(c1, c2, mode);
static public int blendColor(int c1, int c2, int mode) {
return PGraphics.blendColor(c1, c2, mode);
}
public void blend(int sx, int sy, int dx, int dy, int mode) {
if (recorder != null) recorder.blend(sx, sy, dx, dy, mode);
g.blend(sx, sy, dx, dy, mode);
}
public void blend(PImage src,
int sx, int sy, int dx, int dy, int mode) {
if (recorder != null) recorder.blend(src, sx, sy, dx, dy, mode);
g.blend(src, sx, sy, dx, dy, mode);
static public int lerpColor(int c1, int c2, float amt) {
return PGraphics.lerpColor(c1, c2, amt);
}
@@ -6575,6 +6673,12 @@ public class PApplet extends Applet
}
public void setMainDrawingSurface() {
if (recorder != null) recorder.setMainDrawingSurface();
g.setMainDrawingSurface();
}
public void hint(int which) {
if (recorder != null) recorder.hint(which);
g.hint(which);
+36 -14
View File
@@ -36,12 +36,6 @@ import java.awt.image.*;
*/
public abstract class PGraphics extends PImage implements PConstants {
/***
* Parent applet as passed in by the constructor. If null, then
* no MemoryImageSource will be used or updated, saving memory.
*/
PApplet parent;
/// width minus one (useful for many calculations)
public int width1;
@@ -60,6 +54,16 @@ public abstract class PGraphics extends PImage implements PConstants {
/// true if in the midst of resize (no drawing can take place)
boolean insideResize;
// ........................................................
/**
* true if this is the main drawing surface for a particular sketch.
* This would be set to false for an offscreen buffer or if it were
* created any other way than size(). When this is set, the listeners
* are also added to the sketch.
*/
protected boolean mainDrawingSurface;
// ........................................................
// specifics for java memoryimagesource
@@ -488,10 +492,10 @@ public abstract class PGraphics extends PImage implements PConstants {
* @param iwidth viewport width
* @param iheight viewport height
*/
public PGraphics(int iwidth, int iheight) {
this(iwidth, iheight, null);
//public PGraphics(int iwidth, int iheight) {
//this(iwidth, iheight, null);
//resize(iwidth, iheight);
}
//}
/**
@@ -503,11 +507,14 @@ public abstract class PGraphics extends PImage implements PConstants {
* @param iwidth viewport width
* @param iheight viewport height
*/
public PGraphics(int iwidth, int iheight, PApplet applet) {
public PGraphics(int iwidth, int iheight, PApplet parent) {
/*
if (applet != null) {
this.parent = applet;
applet.addListeners();
}
*/
this.parent = parent;
resize(iwidth, iheight);
}
@@ -535,10 +542,25 @@ public abstract class PGraphics extends PImage implements PConstants {
/**
* Parent thread has requested that visual action be taken.
* Set this as the main drawing surface. Meaning that it can safely be
* set to opaque (given a default gray background) and listeners for
* the mouse and keyboard added.
* <p/>
* This should only be used by subclasses of PGraphics.
*/
public void requestDisplay(PApplet parent) { // ignore
parent.handleDisplay();
public void setMainDrawingSurface() {
mainDrawingSurface = true;
parent.addListeners();
}
/**
* Parent thread has requested that visual action be taken.
* This is broken out like this because the OpenGL library
* handles updates in a very different way.
*/
public void requestDisplay(PApplet pa) { // ignore
pa.handleDisplay();
}
@@ -629,7 +651,7 @@ public abstract class PGraphics extends PImage implements PConstants {
// they have to call background() themselves, otherwise everything gets
// a gray background (when just a transparent surface or an empty pdf
// is what's desired)
if (parent != null) {
if (mainDrawingSurface) {
background(204);
}
+7 -1
View File
@@ -62,17 +62,22 @@ public class PGraphics2D extends PGraphics {
protected PGraphics2D() { }
/*
public PGraphics2D(int iwidth, int iheight) {
this(iwidth, iheight, null);
}
*/
public PGraphics2D(int iwidth, int iheight, PApplet applet) {
super(iwidth, iheight, applet);
/*
if (applet != null) {
this.parent = applet;
applet.addListeners();
}
resize(iwidth, iheight);
*/
}
@@ -93,7 +98,8 @@ public class PGraphics2D extends PGraphics {
for (int i = 0; i < pixelCount; i++) pixels[i] = backgroundColor;
//for (int i = 0; i < pixelCount; i++) pixels[i] = 0xffffffff;
if (parent != null) {
//if (parent != null) {
if (mainDrawingSurface) {
cm = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff);;
mis = new MemoryImageSource(width, height, pixels, 0, width);
mis.setFullBufferUpdates(true);
@@ -186,9 +186,11 @@ public class PGraphics3D extends PGraphics {
}
/*
public PGraphics3D(int iwidth, int iheight) {
this(iwidth, iheight, null);
}
*/
/**
@@ -1253,6 +1253,7 @@ public class PGraphicsJava2D extends PGraphics {
//////////////////////////////////////////////////////////////
/*
public void blend(PImage src, int sx, int sy, int dx, int dy, int mode) {
loadPixels();
super.blend(src, sx, sy, dx, dy, mode);
@@ -1265,6 +1266,7 @@ public class PGraphicsJava2D extends PGraphics {
super.blend(sx, sy, dx, dy, mode);
updatePixels();
}
*/
public void blend(int sx1, int sy1, int sx2, int sy2,
+64 -145
View File
@@ -28,8 +28,6 @@ import java.awt.image.*;
import java.io.*;
import java.lang.reflect.*;
//import javax.imageio.*;
/**
* Storage class for pixel data. This is the base class for most image and
@@ -52,6 +50,12 @@ public class PImage implements PConstants, Cloneable {
public int width, height;
// would scan line be useful? maybe for pow of 2 gl textures
/**
* Path to parent object that will be used with save().
* This prevents users from needing savePath() to use PImage.save().
*/
public PApplet parent;
// note! inherited by PGraphics
public int imageMode = CORNER;
public boolean smooth = false;
@@ -107,6 +111,7 @@ public class PImage implements PConstants, Cloneable {
*/
public PImage(int width, int height) {
init(width, height, RGB);
//init(width, height, RGB);
//this(new int[width * height], width, height, ARGB);
// toxi: is it maybe better to init the image with max alpha enabled?
//for(int i=0; i<pixels.length; i++) pixels[i]=0xffffffff;
@@ -124,19 +129,10 @@ public class PImage implements PConstants, Cloneable {
}
/*
public PImage(int pixels[], int width, int height, int format) {
this.pixels = pixels;
this.width = width;
this.height = height;
this.format = format;
this.cache = null;
}
*/
/**
* Function to be used by subclasses to setup their own bidness.
* Used by Capture and Movie classes (and perhaps others),
* because the width/height will not be known when super() is called.
*/
public void init(int width, int height, int format) { // ignore
this.width = width;
@@ -226,93 +222,6 @@ public class PImage implements PConstants, Cloneable {
// MARKING IMAGE AS MODIFIED / FOR USE w/ GET/SET
/*
public int[] loadPixels() {
return getPixels(0, 0, width, height);
}
*/
/**
* Note that when using imageMode(CORNERS),
* the x2 and y2 positions are non-inclusive.
*/
/*
public int[] loadPixels(int x1, int y1, int x2, int y2) {
if (modified) {
// have to set the modified region to include the min/max
// of the coordinates coming in.
// also, mustn't get the pixels for the section that's
// already been marked as modified. gah.
// too complicated, just throw an error
String msg =
"getPixels(x, y, w, h) cannot be used multiple times. " +
"Use getPixels() once to get the entire image instead.";
throw new RuntimeException(msg);
}
if (imageMode == CORNER) { // x2, y2 are w/h
x2 += x1;
y2 += y1;
}
if (pixels == null) { // this is a java 1.3 buffered image
if (image == null) { // this is just an error
throw new RuntimeException("PImage not properly setup for getPixels()");
} else {
pixels = new int[width*height];
}
}
if (image == null) {
// this happens when using just the 1.1 library
// no need to do anything, since the pixels have already been grabbed
} else {
// copy the contents of the buffered image to pixels[]
//((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, width);
try {
//System.out.println("running getrgb...");
Class bufferedImageClass =
Class.forName("java.awt.image.BufferedImage");
// getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)
Method getRgbMethod =
bufferedImageClass.getMethod("getRGB", new Class[] {
Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE,
int[].class, Integer.TYPE, Integer.TYPE
});
getRgbMethod.invoke(image, new Object[] {
new Integer(x1), new Integer(y1),
new Integer(x2 - x1 + 1), new Integer(y2 - y1 + 1),
pixels, new Integer(0), new Integer(width)
});
} catch (Exception e) {
e.printStackTrace();
}
}
return pixels; // just to be nice
}
*/
/*
public void loadPixels() { // ignore
System.err.println("Use loadPixels() instead of loadPixels() " +
"with release 0116 and later.");
loadPixels();
}
public void updatePixels() {
System.err.println("Use updatePixels() instead of updatePixels() " +
"with release 0116 and later.");
System.err.flush();
updatePixels();
}
*/
/**
* Call this when you want to mess with the pixels[] array.
* Formerly called loadPixels().
@@ -374,15 +283,7 @@ public class PImage implements PConstants, Cloneable {
}
}
//public void pixelsUpdated() {
//mx1 = Integer.MAX_VALUE;
//my1 = Integer.MAX_VALUE;
//mx2 = -Integer.MAX_VALUE;
//my2 = -Integer.MAX_VALUE;
//modified = false;
//}
//////////////////////////////////////////////////////////////
@@ -1151,10 +1052,10 @@ public class PImage implements PConstants, Cloneable {
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2) {
if (imageMode == CORNER) { // if CORNERS, do nothing
sx2 += sx1;
sy2 += sy1;
dx2 += dx1;
dy2 += dy1;
sx2 += sx1;
sy2 += sy1;
dx2 += dx1;
dy2 += dy1;
//} else if (imageMode == CENTER) {
//sx2 /= 2f; sy2 /= 2f;
@@ -1185,7 +1086,7 @@ public class PImage implements PConstants, Cloneable {
* REPLACE - destination colour equals colour of source pixel: C = A
* </PRE>
*/
static public int blend(int c1, int c2, int mode) {
static public int blendColor(int c1, int c2, int mode) {
switch (mode) {
case BLEND: return blend_multiply(c1, c2);
case ADD: return blend_add_pin(c1, c2);
@@ -1197,10 +1098,28 @@ public class PImage implements PConstants, Cloneable {
return 0;
}
static public int lerpColor(int c1, int c2, float amt) {
float a1 = ((c1 >> 24) & 0xff);
float r1 = (c1 >> 16) & 0xff;
float g1 = (c1 >> 8) & 0xff;
float b1 = c1 & 0xff;
float a2 = (c2 >> 24) & 0xff;
float r2 = (c2 >> 16) & 0xff;
float g2 = (c2 >> 8) & 0xff;
float b2 = c2 & 0xff;
return (((int) (a1 + (a2-a1)*amt) << 24) |
((int) (r1 + (r2-r1)*amt) << 16) |
((int) (g1 + (g2-g1)*amt) << 8) |
((int) (b1 + (b2-b1)*amt)));
}
/**
* Copies and blends 1 pixel with MODE to pixel in this image.
* Removing this function, the blend() command above can be used instead.
*/
/*
public void blend(int sx, int sy, int dx, int dy, int mode) {
if ((dx >= 0) && (dx < width) && (sx >= 0) && (sx < width) &&
(dy >= 0) && (dy < height) && (sy >= 0) && (sy < height)) {
@@ -1208,11 +1127,13 @@ public class PImage implements PConstants, Cloneable {
blend(pixels[dy * width + dx], pixels[sy * width + sx], mode);
}
}
*/
/**
* Copies and blends 1 pixel with MODE to pixel in another image
*/
/*
public void blend(PImage src,
int sx, int sy, int dx, int dy, int mode) {
if ((dx >= 0) && (dx < width) && (sx >= 0) && (sx < src.width) &&
@@ -1222,6 +1143,7 @@ public class PImage implements PConstants, Cloneable {
src.pixels[sy * src.width + sx], mode);
}
}
*/
/**
@@ -1305,7 +1227,10 @@ public class PImage implements PConstants, Cloneable {
/**
* Duplicate an image, returns new PImage object.
* The pixels[] array for the new object will be unique
* and recopied from the source image.
* and recopied from the source image. This is implemented as an
* override of Object.clone(). We recommend using get() instead,
* because it prevents you from needing to catch the
* CloneNotSupportedException, and from doing a cast from the result.
*/
public Object clone() throws CloneNotSupportedException { // ignore
PImage c = (PImage) super.clone();
@@ -1618,19 +1543,6 @@ public class PImage implements PConstants, Cloneable {
}
/**
* returns the fractional portion of a number: frac(2.3) = .3;
*/
/*
private static float frac(float x) {
return (x - (int) x);
}
*/
/**
* generic linear interpolation
*/
private static int mix(int a, int b, int f) {
return a + (((b - a) * f) >> 8);
}
@@ -1812,7 +1724,7 @@ public class PImage implements PConstants, Cloneable {
protected boolean saveTIFF(OutputStream output) {
if (format != RGB) {
System.err.println("Warning: only RGB information is saved with " +
".tif files. Use .tga or .png if you want alpha.");
".tif files. Use .tga or .png for ARGB images and others.");
}
try {
byte tiff[] = new byte[768];
@@ -1849,7 +1761,7 @@ public class PImage implements PConstants, Cloneable {
/**
* Creates a Targa32 formatted byte sequence of specified
* pixel buffer now using RLE compression.
* pixel buffer using RLE compression.
* </p>
* Also figured out how to avoid parsing the image upside-down
* (there's a header flag to set the image origin to top-left)
@@ -1860,7 +1772,7 @@ public class PImage implements PConstants, Cloneable {
* <LI><TT>RGB</TT> &rarr; 24 bits
* <LI><TT>ARGB</TT> &rarr; 32 bits
* </UL>
* all versions are RLE compressed
* All versions are RLE compressed.
* </p>
* Contributed by toxi 8-10 May 2005, based on this RLE
* <A HREF="http://www.wotsit.org/download.asp?f=tga">specification</A>
@@ -2087,15 +1999,23 @@ public class PImage implements PConstants, Cloneable {
* The ImageIO API claims to support wbmp files, however they probably
* require a black and white image. Basic testing produced a zero-length
* file with no error.
* <p>
* As of revision 0116, savePath() is not needed if this object has been
* created (as recommended) via createImage() or createGraphics() or
* one of its neighbors.
*/
public void save(String filename) { // ignore
public void save(String path) { // ignore
boolean success = false;
File file = new File(filename);
File file = new File(path);
if (!file.isAbsolute()) {
System.err.println("PImage.save() requires an absolute path, " +
"you might need to use savePath().");
return;
if (parent != null) {
//file = new File(parent.savePath(filename));
path = parent.savePath(path);
} else {
throw new RuntimeException("PImage.save() requires an absolute path. Or you can " +
"use createImage() instead or pass savePath() to save().");
}
}
try {
@@ -2116,26 +2036,25 @@ public class PImage implements PConstants, Cloneable {
}
if (saveImageFormats != null) {
for (int i = 0; i < saveImageFormats.length; i++) {
//System.out.println(saveImageFormats[i]);
if (filename.endsWith("." + saveImageFormats[i])) {
saveImageIO(filename);
if (path.endsWith("." + saveImageFormats[i])) {
saveImageIO(path);
return;
}
}
}
}
if (filename.toLowerCase().endsWith(".tga")) {
os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
if (path.toLowerCase().endsWith(".tga")) {
os = new BufferedOutputStream(new FileOutputStream(path), 32768);
success = saveTGA(os); //, pixels, width, height, format);
} else {
if (!filename.toLowerCase().endsWith(".tif") &&
!filename.toLowerCase().endsWith(".tiff")) {
if (!path.toLowerCase().endsWith(".tif") &&
!path.toLowerCase().endsWith(".tiff")) {
// if no .tif extension, add it..
filename += ".tif";
path += ".tif";
}
os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
os = new BufferedOutputStream(new FileOutputStream(path), 32768);
success = saveTIFF(os); //, pixels, width, height);
}
os.flush();
+25 -34
View File
@@ -43,7 +43,10 @@ X remove image(filename) and textFont(filename) et al.
X revision 115 may be saving raw files as TIFF format
X may be a bug specific to java 1.5 (nope)
X http://dev.processing.org/bugs/show_bug.cgi?id=378
X saveFrame() not working for casey
X problem with tiff loading in photoshop etc
X hint(DISABLE_NATIVE_FONTS) to disable the built-in stuff?
_ or maybe this should be hint(ENABLE_NATIVE_FONTS) instead?
X check http:// stuff to see if it's a url first on openStream()
X it's the most harmless, since prolly just a MFUEx
X fix problem where root of exported sketch won't be checked
@@ -61,6 +64,26 @@ X fix dxf to use begin/endDraw instead of begin/endFrame
X fixes axel's bug with dxf export
X set default frameRate cap at 60
X otherwise really thrashing the cpu when not necessary
X jpeg loading may be extremely slow (loadBytes?)
X seems specific to 0115 versus the others
X http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1158111639
X http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1154714548
X http://dev.processing.org/bugs/show_bug.cgi?id=392
X loadImage() problems with png and jpg
X actually it's an issue with some types of jpeg files
X http://dev.processing.org/bugs/show_bug.cgi?id=279
X java.lang.IllegalArgumentException:
X Width (-1) and height (-1) cannot be <= 0
X identical to what happens when the image data is bad
X for instance, trying to load a tiff image with the jpg loader
X http://dev.processing.org/bugs/show_bug.cgi?id=305
o blend() mode param should be moved to the front
X nah, works better with the other format
X make sure there's parity with the copy() functions
X remove single pixel blend functions
o blend() should prolly have its mode be the first param
X move blend() to blendColor() when applying it to a color
X added lerpColor(), though it needs a new name
more recent
X only update mouse pos on moved and dragged
@@ -111,11 +134,8 @@ _ for a PGraphics2D, should its image cache object be the memoryimagesource?
_ is the texture[] array in PGraphics3D causing the problems with memory?
_ actually it's a PGraphicsGL problem..
_ maybe the image binding not getting unbound?
_ jpeg loading may be extremely slow (loadBytes?)
_ seems specific to 0115 versus the others
_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1158111639
_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1154714548
_ loading lots of images is a problem, describe how to unload
_ is it possible? necessary to call delay(5) or something?
api issues
_ remove LINE_LOOP and LINE_STRIP
@@ -187,27 +207,10 @@ _ since camera functions don't even look at it or set it
_ file for 2.0.. stroke on type
_ saveFrame() not working for casey
_ problem with tiff loading in photoshop etc
void setup() {
size(400, 400);
noLoop();
}
void draw() {
line(0, 0, width, height);
line(0, width, height, 0);
saveFrame();
}
_ fonts in java 1.5 have changed again
_ appears that asking for the postscript name no longer works
_ fix "create font" and associated font stuff to straighten it out
_ blend() mode param should be moved to the front
_ make sure there's parity with the copy() functions
_ remove single pixel blend functions
_ blend() should prolly have its mode be the first param
_ add to docs: save() on a PImage needs savePath() added
_ background() with an image ignores the tint.. it's basically like set()
@@ -230,9 +233,6 @@ _ textAlign(CENTER | TOP);
_ could even have textAlign(CENTER) and textAlign(TOP) not replace each other
_ or textAlign(LEFT, MIDDLE); -> this one seems best
_ loading lots of images is a problem, describe how to unload
_ is it possible? necessary to call delay(5) or something?
_ AIOOBE on PLine 757.. halts renderer
X begin/endPixels.. change has been made
@@ -865,15 +865,6 @@ _ http://dev.processing.org/bugs/show_bug.cgi?id=103
CORE / PImage
_ loadImage(url) having trouble with jpeg
_ actually it's an issue with some types of jpeg files
_ http://dev.processing.org/bugs/show_bug.cgi?id=279
_ java.lang.IllegalArgumentException:
_ Width (-1) and height (-1) cannot be <= 0
_ identical to what happens when the image data is bad
_ for instance, trying to load a tiff image with the jpg loader
_ png image loading problems
_ http://dev.processing.org/bugs/show_bug.cgi?id=305
_ don't grab pixels of java2d images unless asked
_ this is the difference between a lot of loadPixels() and not
_ so important to have it in before beta if that's the change
@@ -41,9 +41,9 @@ import com.sun.opengl.util.*;
* JOGL requires Java 1.4 or higher, so there are no restrictions on this
* code to be compatible with Java 1.1 or Java 1.3.
* <p/>
* This code relies on PGraphics3 for all lighting and transformations.
* This code relies on PGraphics3D for all lighting and transformations.
* Meaning that translate(), rotate(), and any lighting will be done in
* PGraphics3, and OpenGL is only used to blit lines and triangles as fast
* PGraphics3D, and OpenGL is only used to blit lines and triangles as fast
* as it possibly can.
* <p/>
* For this reason, OpenGL may not be accelerated as far as it could be,
@@ -98,15 +98,16 @@ public class PGraphicsOpenGL extends PGraphics3D {
* be null for this renderer because OpenGL uses a special Canvas
* object that must be added to a component (the host PApplet, in this case)
* that is visible on screen in order to work properly.
* @param applet the host applet
* @param parent the host applet
*/
public PGraphicsOpenGL(int width, int height, PApplet applet) {
public PGraphicsOpenGL(int width, int height, PApplet iparent) {
//System.out.println("creating PGraphicsGL");
if (applet == null) {
if (iparent == null) {
throw new RuntimeException("The applet passed to PGraphicsGL " +
"cannot be null");
}
this.parent = iparent;
//System.out.println("creating PGraphicsGL 2");
@@ -115,13 +116,10 @@ public class PGraphicsOpenGL extends PGraphics3D {
canvas = new GLCanvas();
//System.out.println("creating PGraphicsGL 3");
final PApplet parent = applet;
canvas.addGLEventListener(new GLEventListener() {
public void display(GLAutoDrawable drawable) {
// need to get a fresh opengl object here
//gl = canvas.getGL();
gl = drawable.getGL();
parent.handleDisplay(); // this means it's time to go
}
@@ -138,16 +136,16 @@ public class PGraphicsOpenGL extends PGraphics3D {
//System.out.println("creating PGraphicsGL 4");
applet.setLayout(null);
applet.add(canvas);
parent.setLayout(null);
parent.add(canvas);
canvas.setBounds(0, 0, width, height);
//System.out.println("creating PGraphicsGL 5");
//System.out.println("adding canvas listeners");
canvas.addMouseListener(applet);
canvas.addMouseMotionListener(applet);
canvas.addKeyListener(applet);
canvas.addFocusListener(applet);
canvas.addMouseListener(parent);
canvas.addMouseMotionListener(parent);
canvas.addKeyListener(parent);
canvas.addFocusListener(parent);
//System.out.println("creating PGraphicsGL 6");
@@ -184,8 +182,17 @@ public class PGraphicsOpenGL extends PGraphics3D {
//System.out.println("done creating gl");
}
/**
* Overridden from base PGraphics, because this PGraphics will set its own listeners.
*/
public void setMainDrawingSurface() {
mainDrawingSurface = true;
//parent.addListeners();
}
//protected boolean displayed = false;
// main applet thread requests an update,
@@ -1791,7 +1798,7 @@ public class PGraphicsOpenGL extends PGraphics3D {
//////////////////////////////////////////////////////////////
public void beginPixels() {
public void loadPixels() {
if ((pixels == null) || (pixels.length != width*height)) {
pixels = new int[width * height];
pixelBuffer = BufferUtil.newIntBuffer(pixels.length);
@@ -2080,7 +2087,7 @@ public class PGraphicsOpenGL extends PGraphics3D {
}
public void endPixels() {
public void updatePixels() {
// flip vertically (opengl stores images upside down),
int index = 0;
@@ -2152,14 +2159,7 @@ public class PGraphicsOpenGL extends PGraphics3D {
GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixelBuffer);
}
public void endPixels(int x, int y, int c, int d) {
//throw new RuntimeException("endPixels() not available with OpenGL");
// TODO make this actually work for a smaller region
// problem is, it gets pretty messy with the y reflection, etc
endPixels();
}
//////////////////////////////////////////////////////////////
@@ -2310,9 +2310,9 @@ public class PGraphicsOpenGL extends PGraphics3D {
public void copy(int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2) {
//throw new RuntimeException("copy() not available with OpenGL");
beginPixels();
loadPixels();
super.copy(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
endPixels();
updatePixels();
}
@@ -2324,9 +2324,9 @@ public class PGraphicsOpenGL extends PGraphics3D {
public void copy(PImage src,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2) {
beginPixels();
loadPixels();
super.copy(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
endPixels();
updatePixels();
}
@@ -2334,13 +2334,13 @@ public class PGraphicsOpenGL extends PGraphics3D {
public void blend(int sx, int sy, int dx, int dy, int mode) {
set(dx, dy, PImage.blend(get(sx, sy), get(dx, dy), mode));
set(dx, dy, PImage.blendColor(get(sx, sy), get(dx, dy), mode));
}
public void blend(PImage src,
int sx, int sy, int dx, int dy, int mode) {
set(dx, dy, PImage.blend(src.get(sx, sy), get(dx, dy), mode));
set(dx, dy, PImage.blendColor(src.get(sx, sy), get(dx, dy), mode));
}
@@ -2351,9 +2351,9 @@ public class PGraphicsOpenGL extends PGraphics3D {
*/
public void blend(int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2, int mode) {
beginPixels();
loadPixels();
super.blend(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode);
endPixels();
updatePixels();
}
@@ -2365,9 +2365,9 @@ public class PGraphicsOpenGL extends PGraphics3D {
public void blend(PImage src,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2, int mode) {
beginPixels();
loadPixels();
super.blend(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode);
endPixels();
updatePixels();
}
@@ -2375,7 +2375,7 @@ public class PGraphicsOpenGL extends PGraphics3D {
public void save(String filename) {
beginPixels();
loadPixels();
super.save(filename);
}
+3 -3
View File
@@ -75,9 +75,9 @@ _ under the memory section, getting free/total memory
_ long allocated = Runtime.getRuntime().totalMemory() (-Xms usually)
_ long allocatedButFree = Runtime.getRuntime().freeMemory() (-Xms minus used)
_ long maximum = Runtime.getRuntime().maxMemory() (-Xmx setting)
_ remove the memory setting stuff from the faq
_ add more information about setting the memory
_ move memory setting to troubleshooting page on bugs db
X remove the memory setting stuff from the faq
X add more information about setting the memory
X move memory setting to troubleshooting page on bugs db
mac faq
X windows, may need to install new version of video drivers
+4 -2
View File
@@ -51,7 +51,9 @@ public class Capture extends PImage implements Runnable {
static public final int PAL = StdQTConstants.palIn;
static public final int SECAM = StdQTConstants.secamIn;
PApplet parent;
// no longer needed because parent field added to PImage
//PApplet parent;
Method captureEventMethod;
String name; // keep track for error messages (unused)
Thread runner;
@@ -129,7 +131,7 @@ public class Capture extends PImage implements Runnable {
* <P/>
* If the following function:
* <PRE>public void captureEvent(Capture c)</PRE>
* is defined int the host PApplet, then it will be called every
* is defined in the host PApplet, then it will be called every
* time a new frame is available from the capture device.
*/
public Capture(PApplet parent, String name,
+5 -4
View File
@@ -40,7 +40,9 @@ import quicktime.util.RawEncodedImage;
public class Movie extends PImage implements PConstants, Runnable {
PApplet parent;
// no longer needing a reference to the parent because PImage has one
//PApplet parent;
Method movieEventMethod;
String filename;
Thread runner;
@@ -90,7 +92,7 @@ public class Movie extends PImage implements PConstants, Runnable {
public Movie(PApplet parent, String filename, int ifps) {
// this creates a fake image so that the first time this
// attempts to draw, something happens that's not an exception
super.init(1, 1, RGB);
super(1, 1, RGB);
this.parent = parent;
@@ -417,8 +419,7 @@ public class Movie extends PImage implements PConstants, Runnable {
if (dataWidth != movieWidth) {
if (removeBorders) {
int bpixels[] = new int[dataWidth * movieHeight];
borderImage = new PImage(bpixels, dataWidth, movieHeight, RGB);
borderImage = new PImage(dataWidth, movieHeight, RGB);
} else {
movieWidth = dataWidth;
}