Hello,

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();
    }

}

Reply via email to