fixing tint() problems with java2d, remove reflection from PImage

This commit is contained in:
benfry
2007-10-23 00:13:27 +00:00
parent 5271594f88
commit 05e787f5b6
3 changed files with 150 additions and 38 deletions
+109 -5
View File
@@ -652,7 +652,7 @@ public class PGraphicsJava2D extends PGraphics {
who.modified = false;
}
g2.drawImage(((ImageCache) who.cache).image,
g2.drawImage(((ImageCache) who.cache).image,
(int) x1, (int) y1, (int) x2, (int) y2,
u1, v1, u2, v2, null);
}
@@ -662,18 +662,122 @@ public class PGraphicsJava2D extends PGraphics {
PImage source;
boolean tinted;
int tintedColor;
int tintedPixels[];
int tintedPixels[]; // one row of tinted pixels
BufferedImage image;
public ImageCache(PImage source) {
this.source = source;
// even if RGB, set the image type to ARGB, because the
// image may have an alpha value for its tint().
int type = BufferedImage.TYPE_INT_ARGB;
// int type = BufferedImage.TYPE_INT_ARGB;
//System.out.println("making new buffered image");
image = new BufferedImage(source.width, source.height, type);
// image = new BufferedImage(source.width, source.height, type);
}
/**
* Update the pixels of the cache image. Already determined that the tint
* has changed, or the pixels have changed, so should just go through
* with the update without further checks.
*/
public void update(boolean tint, int tintColor) {
int bufferType = BufferedImage.TYPE_INT_ARGB;
boolean opaque = (tintColor & 0xFF000000) == 0xFF000000;
if (source.format == RGB) {
if (!tint || (tint && opaque)) {
bufferType = BufferedImage.TYPE_INT_RGB;
}
}
boolean wrongType = (image != null) && (image.getType() != bufferType);
if ((image == null) || wrongType) {
image = new BufferedImage(source.width, source.height, bufferType);
}
WritableRaster wr = image.getRaster();
if (tint) {
if (tintedPixels == null || tintedPixels.length != source.width) {
tintedPixels = new int[source.width];
}
int a2 = (tintColor >> 24) & 0xff;
int r2 = (tintColor >> 16) & 0xff;
int g2 = (tintColor >> 8) & 0xff;
int b2 = (tintColor) & 0xff;
if (bufferType == BufferedImage.TYPE_INT_RGB) {
//int alpha = tintColor & 0xFF000000;
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int x = 0; x < source.width; x++) {
int argb1 = source.pixels[index++];
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
int b1 = (argb1) & 0xff;
tintedPixels[x] = //0xFF000000 |
(((r2 * r1) & 0xff00) << 8) |
((g2 * g1) & 0xff00) |
(((b2 * b1) & 0xff00) >> 8);
}
wr.setDataElements(0, y, source.width, 1, tintedPixels);
}
// could this be any slower?
// float[] scales = { tintR, tintG, tintB };
// float[] offsets = new float[3];
// RescaleOp op = new RescaleOp(scales, offsets, null);
// op.filter(image, image);
} else if (bufferType == BufferedImage.TYPE_INT_ARGB) {
int index = 0;
for (int y = 0; y < source.height; y++) {
if (source.format == RGB) {
int alpha = tintColor & 0xFF000000;
for (int x = 0; x < source.width; x++) {
int argb1 = source.pixels[index++];
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
int b1 = (argb1) & 0xff;
tintedPixels[x] = alpha |
(((r2 * r1) & 0xff00) << 8) |
((g2 * g1) & 0xff00) |
(((b2 * b1) & 0xff00) >> 8);
}
} else if (source.format == ARGB) {
for (int x = 0; x < source.width; x++) {
int argb1 = source.pixels[index++];
int a1 = (argb1 >> 24) & 0xff;
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
int b1 = (argb1) & 0xff;
tintedPixels[x] =
(((a2 * a1) & 0xff00) << 16) |
(((r2 * r1) & 0xff00) << 8) |
((g2 * g1) & 0xff00) |
(((b2 * b1) & 0xff00) >> 8);
}
} else if (source.format == ALPHA) {
int lower = tintColor & 0xFFFFFF;
for (int x = 0; x < source.width; x++) {
int a1 = source.pixels[index++];
tintedPixels[x] =
(((a2 * a1) & 0xff00) << 16) | lower;
}
}
wr.setDataElements(0, y, source.width, 1, tintedPixels);
}
// Not sure why ARGB images take the scales in this order...
// float[] scales = { tintR, tintG, tintB, tintA };
// float[] offsets = new float[4];
// RescaleOp op = new RescaleOp(scales, offsets, null);
// op.filter(image, image);
}
} else {
wr.setDataElements(0, 0, source.width, source.height, source.pixels);
}
this.tinted = tint;
this.tintedColor = tintColor;
}
}
/*
// for rev 0124, passing the tintColor in here. the problem is that
// the 'parent' PGraphics object of this inner class may not be
// the same one that's used when drawing. for instance, if this
@@ -785,7 +889,7 @@ public class PGraphicsJava2D extends PGraphics {
raster.setDataElements(0, 0, source.width, source.height, tintedPixels);
}
}
}
*/
//////////////////////////////////////////////////////////////
+33 -25
View File
@@ -24,9 +24,10 @@
package processing.core;
import java.awt.Image;
import java.awt.image.*;
import java.io.*;
import java.lang.reflect.*;
import javax.imageio.ImageIO;
/**
@@ -60,8 +61,8 @@ public class PImage implements PConstants, Cloneable {
public int imageMode = CORNER;
public boolean smooth = false;
/** native storage for java 1.3 image object */
//public Object image;
/** Native Java image object */
//public Image image;
/** for subclasses that need to store info about the image */
public Object cache;
@@ -230,6 +231,7 @@ public class PImage implements PConstants, Cloneable {
* this should copy all data into the pixels[] array
*/
public void loadPixels() { // ignore
}
@@ -2445,10 +2447,11 @@ public class PImage implements PConstants, Cloneable {
*/
protected void saveImageIO(String path) throws IOException {
try {
//BufferedImage bimage =
// new BufferedImage(width, height, (format == ARGB) ?
// BufferedImage.TYPE_INT_ARGB :
// BufferedImage.TYPE_INT_RGB);
BufferedImage bimage =
new BufferedImage(width, height, (format == ARGB) ?
BufferedImage.TYPE_INT_ARGB :
BufferedImage.TYPE_INT_RGB);
/*
Class bufferedImageClass =
Class.forName("java.awt.image.BufferedImage");
Constructor bufferedImageConstructor =
@@ -2466,8 +2469,10 @@ public class PImage implements PConstants, Cloneable {
new Integer(height),
new Integer((format == ARGB) ? typeIntArgb : typeIntRgb)
});
*/
//bimage.setRGB(0, 0, width, height, pixels, 0, width);
bimage.setRGB(0, 0, width, height, pixels, 0, width);
/*
Method setRgbMethod =
bufferedImageClass.getMethod("setRGB", new Class[] {
Integer.TYPE, Integer.TYPE,
@@ -2480,11 +2485,13 @@ public class PImage implements PConstants, Cloneable {
new Integer(width), new Integer(height),
pixels, new Integer(0), new Integer(width)
});
*/
File file = new File(path);
String extension = path.substring(path.lastIndexOf('.') + 1);
//ImageIO.write(bimage, extension, file);
ImageIO.write(bimage, extension, file);
/*
Class renderedImageClass =
Class.forName("java.awt.image.RenderedImage");
Class ioClass = Class.forName("javax.imageio.ImageIO");
@@ -2493,6 +2500,7 @@ public class PImage implements PConstants, Cloneable {
renderedImageClass, String.class, File.class
});
writeMethod.invoke(null, new Object[] { bimage, extension, file });
*/
} catch (Exception e) {
e.printStackTrace();
@@ -2509,6 +2517,9 @@ public class PImage implements PConstants, Cloneable {
* As of revision 0100, this function requires an absolute path,
* in order to avoid confusion. To save inside the sketch folder,
* use the function savePath() from PApplet, or use saveFrame() instead.
* 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.
* <p>
* As of revision 0115, when using Java 1.4 and later, you can write
* to several formats besides tga and tiff. If Java 1.4 is installed
@@ -2517,16 +2528,13 @@ public class PImage implements PConstants, Cloneable {
* To get a list of the supported formats for writing, use: <BR>
* <TT>println(javax.imageio.ImageIO.getReaderFormatNames())</TT>
* <p>
* To use the original built-in image writers, use .tga as the extension,
* or don't include an extension, in which case .tif will be added.
* To use the original built-in image writers, use .tga or .tif as the
* extension, or don't include an extension. When no extension is used,
* the extension .tif will be added to the file name.
* <p>
* 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 path) { // ignore
boolean success = false;
@@ -2548,16 +2556,16 @@ public class PImage implements PConstants, Cloneable {
if (PApplet.javaVersion >= 1.4f) {
if (saveImageFormats == null) {
//saveImageFormats = javax.imageio.ImageIO.getWriterFormatNames();
try {
Class ioClass = Class.forName("javax.imageio.ImageIO");
Method getFormatNamesMethod =
ioClass.getMethod("getWriterFormatNames", (Class[]) null);
saveImageFormats = (String[])
getFormatNamesMethod.invoke((Class[]) null, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
saveImageFormats = javax.imageio.ImageIO.getWriterFormatNames();
// try {
// Class ioClass = Class.forName("javax.imageio.ImageIO");
// Method getFormatNamesMethod =
// ioClass.getMethod("getWriterFormatNames", (Class[]) null);
// saveImageFormats = (String[])
// getFormatNamesMethod.invoke((Class[]) null, (Object[]) null);
// } catch (Exception e) {
// e.printStackTrace();
// }
}
if (saveImageFormats != null) {
for (int i = 0; i < saveImageFormats.length; i++) {
+8 -8
View File
@@ -1,5 +1,11 @@
0132 core
X an image marked RGB but with 0s for the alpha won't draw in JAVA2D
X images with 0x00 in their high bits being drawn transparent
X also if transparency set but RGB is setting, still honors transparency
X http://dev.processing.org/bugs/show_bug.cgi?id=351
X tint() and noTint() switching problem in P2D
X this should be a quick fix
X http://dev.processing.org/bugs/show_bug.cgi?id=222
_ fix svg caps/joins for opengl with svg library
_ http://dev.processing.org/bugs/show_bug.cgi?id=628
@@ -26,6 +32,7 @@ _ and that java2d should complain if people try it
_ add hint() and unhint()
_ also add unhint() to the keywords file
_ and maybe remove hint() from keywords_base?
_ method to go from function name to the included examples where used?
createGraphics() mess
_ text characters showing up as opaque rectangles in tga files
@@ -61,13 +68,6 @@ _ make a note that updatePixels() only sets a flag in PImage
_ (but not PGraphics, which does it immediately)
tint/textures
_ an image marked RGB but with 0s for the alpha won't draw in JAVA2D
_ images with 0x00 in their high bits being drawn transparent
_ also if transparency set but RGB is setting, still honors transparency
_ http://dev.processing.org/bugs/show_bug.cgi?id=351
_ tint() and noTint() switching problem in P2D
_ this should be a quick fix
_ http://dev.processing.org/bugs/show_bug.cgi?id=222
_ related to the fill bugs: when fill is identical, no fill applied
_ actually tint() should take over for fill as per-vertex color
_ when textured images are being used