I am trying to scale a BufferedImage with an
IndexColorModel (bits=1, values=2) using drawImage on
a Graphics2D object, that belongs to a JPanel.
I always get
java.lang.IllegalArgumentException: Raster BytePackedRaster: width =
50 height =
50 #channels 1 xOff = 0 yOff = 0 is incompatible with ColorModel
IndexColorMode
l: #pixelBits = 1 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@
31294c7e transparency = 2 transIndex = 2 has alpha = true
isAlphaPre = false
at java.awt.image.BufferedImage.<init>(BufferedImage.java:521)
at sun.java2d.SunGraphics2D.renderingPipeImage(SunGraphics2D.java:2120)
at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:1769)
if I define a scaling. If I only use a translation when
doing drawImage it does not throw exceptions, but the output
looks wrong. I wrote a workaround, where I first copy the
image as is into a new BufferedImage with a
555-RGB ColorModel and then scale that, which works,
but it takes an awful lot of memory (and often OutOfMemoryErrors,
as the BW pictures are huge: 1600*1200 pixels).
For details please run the attached java program to show the problems.
Any ideas, how to scale BW Rasters into a Graphics2D object, without using too much memory?
Greetings,
Knut
-- Knut H. Meyer Phone: +49-711/13353-44 FAX: +49-711/1335353 Email: [EMAIL PROTECTED] D A N E T - IS GmbH Waldburgstrasse 17 - 19, D-70563 Stuttgart
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
import java.util.*;
import java.awt.image.*;
public class ImageTest implements ImageObserver
{
private static final int x1 = 50;
private static final int y1 = 50;
private static final int x2 = 200;
private static final int y2 = 200;
private static final int x3 = 350;
private static final int y3 = 350;
private static final int x4 = 500;
private static final int y4 = 500;
private static int w = 50;
private static int h = 50;
private static BufferedImage image;
private static ImageTest test;
public boolean imageUpdate(Image image, int infoFlags, int b, int c, int d, int e)
{
return ((infoFlags & ImageObserver.ALLBITS) == 0);
}
public void drawImageWorkAround(Image image,
int x,
int y,
Graphics2D graphics)
{
int pictureWidth = image.getWidth(this);
int pictureHeight = image.getHeight(this);
AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
trans.scale((double)w/(double)pictureWidth, (double)h/(double)pictureHeight);
BufferedImage copy = new BufferedImage(pictureWidth,
pictureHeight,
BufferedImage.TYPE_USHORT_565_RGB);
Graphics2D g = copy.createGraphics();
g.setBackground(Color.white);
g.clearRect(0,0, pictureWidth, pictureHeight);
g.drawImage(image, null, null);
// now scale it
graphics.drawImage(copy, trans, null);
copy = null;
}
public void drawImageIntended(Image image,
int x,
int y,
Graphics2D graphics)
{
int pictureWidth = image.getWidth(this);
int pictureHeight = image.getHeight(this);
AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
trans.scale((double)w/(double)pictureWidth, (double)h/(double)pictureHeight);
graphics.drawImage(image, trans, null);
}
public void drawImageWorksNot1(Image image,
int x,
int y,
Graphics2D graphics)
{
AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
graphics.drawImage(image, trans, null);
}
public void drawImageWorksNot2(Image image,
int x,
int y,
Graphics2D graphics)
{
AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
int pictureWidth = image.getWidth(this);
int pictureHeight = image.getHeight(this);
Image scaledImage =
image.getScaledInstance((int)((double)w/(double)pictureWidth),
(int)((double)h/(double)pictureHeight),
Image.SCALE_DEFAULT);
scaledImage.getWidth(this);
graphics.drawImage(scaledImage, trans, null);
}
public static void main(String argv[])
{
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
};
javax.swing.JFrame frame = new javax.swing.JFrame("Font Test");
frame.setBackground(Color.white);
frame.getContentPane().setLayout(new BorderLayout());
// create a bitmap array
int bytesPerRow = 50;
int height = 50;
byte pattern[] = new byte[bytesPerRow*height];
for(int i = 0 ; i < bytesPerRow*height; i++)
{
pattern[i] = (byte)(i % 256);
}
// Create Color Model
byte[] lookupTable = new byte[] { (byte)255, (byte)0 };
IndexColorModel cm =
new IndexColorModel(1, // One bit per pixel
2, // Two values in the component arrays
lookupTable, // Red Components
lookupTable, // Green Components
lookupTable); // Blue Components
// Create Raster from DataBufferByte
DataBuffer db = new DataBufferByte(pattern,
bytesPerRow*height);
WritableRaster r = Raster.createPackedRaster(db, bytesPerRow*8, height, 1, null);
// Create BufferedImage from ColorModel and Raster
image = new BufferedImage(cm, r, false, null);
test = new ImageTest();
JPanel panel = new JPanel()
{
public void paint(Graphics g)
{
Graphics2D graphics = (Graphics2D) g;
graphics.setBackground(Color.white);
graphics.clearRect(0,0, getWidth(), getHeight());
test.drawImageWorksNot1(image, x1, y1, graphics);
try
{
test.drawImageIntended(image, x2, y2, graphics);
}
catch(Exception e)
{
e.printStackTrace();
}
test.drawImageWorkAround(image, x3, y3, graphics);
try
{
test.drawImageWorksNot2(image, x4, y4, graphics);
}
catch(Exception e)
{
e.printStackTrace();
}
}
};
frame.getContentPane().add("Center", panel);
frame.addWindowListener(listener);
frame.pack();
frame.setSize(940,640);
// display the stuff
frame.show();
}
}
