mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
fixing tint() problems with java2d, remove reflection from PImage
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user