开发者

java.lang.IllegalArgumentException: Number of scaling constants does not equal the number of of color or color/alpha components

I am writing aplha composite test app b开发者_开发百科ased on this example

/* Create an ARGB BufferedImage */
   BufferedImage img = (BufferedImage)image;//ImageIO.read(imageSrc);
   int w = img.getWidth(null);
   int h = img.getHeight(null);
   BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR_PRE);
   Graphics g = bi.getGraphics();
   g.drawImage(img, 0, 0, null);

   /* Create a rescale filter op that makes the image 50% opaque */
   float[] scales = { 1f, 1f, 1f, 1f };
   float[] offsets = new float[4];
   RescaleOp rop = new RescaleOp(scales, offsets, null);

   /* Draw the image, applying the filter */
   g2d.drawImage(bi, rop, 0, 0);

source link: http://download.oracle.com/javase/tutorial/2d/images/drawimage.html

It works fine with simple images but with photos (jpg etc) I get this exception like:

java.lang.IllegalArgumentException: Number of scaling constants does not equal the number of of color or color/alpha components

To be more clear... Here is my adapted test code class. This code style throws the exception...

public class ImageTest extends JLabel {

    public Image image;
    private BufferedImage bImage;
    ImageObserver imageObserver;
    float[] scales = {1f, 1f, 1f, 1f};
    float[] offsets = new float[4];
    RescaleOp rop;
    int width;
    int height;

    public ImageTest(ImageIcon icon) {

        width = icon.getIconWidth();
        height = icon.getIconHeight();

        this.image = icon.getImage();
        this.imageObserver = icon.getImageObserver();

        //this.bImage=(BufferedImage)image; //previous version (makes exception?)...

        this.bImage = new BufferedImage(
            width, height, BufferedImage.TYPE_INT_ARGB);
        this.bImage.createGraphics().drawImage(
            this.image, 0, 0, width, height, imageObserver);

        rop = new RescaleOp(scales, offsets, null);
        this.repaint();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(this.bImage, rop, 0, 0);
    }

    public void setRescaleOp(RescaleOp rop) {
        this.rop = rop;
    }
}//class end

I am not pretty sure where the exception comes from so I need your advice where to look at?

P.S. I suppose it is the IndexColorModel problem but if so I am not sure how to fix it...

Any useful comment is appreciated :)

Andrew


Using the example below and the image you provided, I am unable to reproduce the effect you describe.

I was puzzled that a BufferedImage of TYPE_4BYTE_ABGR_PRE has a ComponentColorModel, in contrast to the more familiar DirectColorModel, but it's an IndexColorModel that cannot be rescaled.

Addendum: Updated code to use filter(), as the previous version was incorrectly reusing the BufferedImage.

Addendum: In another answer, you said,

I don't want to create a new BufferedImage each time. I want to filter the image on the fly using a JSlider.

The example you cited does this by creating the BufferedImage once in the SeeThroughComponent constructor and then adjusting just the RescaleOp in the slider's change handler. It seems quite responsive.

Addendum: In an edit to your question, you mention that the IllegalArgumentException may arise when encountering an image having an IndexColorModel. I am able to reproduce this using, e.g. TYPE_BYTE_INDEXED. You may be able to work around such images by trapping the exception and rendering them separately as shown here.

java.lang.IllegalArgumentException: Number of scaling constants does not equal the number of of color or color/alpha components

import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/questions/5838842 */
public class RescaleOpTest extends JPanel {

    public static final String LINK =
        "http://www.freeimagehosting.net/uploads/576c64ef7b.png";

    public RescaleOpTest() {
        this.setLayout(new GridLayout(1, 0));
        Image img = null;
        try {
            img = ImageIO.read(new URL(LINK));
//            img = ImageIO.read(new File("image.jpg"));
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
        int w = img.getWidth(null);
        int h = img.getHeight(null);
        BufferedImage bi = new BufferedImage(
            w, h, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        Graphics2D g = bi.createGraphics();
        g.drawImage(img, 0, 0, null);
        g.dispose();

        /* Create a rescale filter op that makes the image 75% opaque */
        float[] scales = {1f, 1f, 1f, 0.75f};
        float[] offsets = new float[4];
        RescaleOp rop = new RescaleOp(scales, offsets, null);
        bi = rop.filter(bi, null);
        this.add(new JLabel(new ImageIcon(img)));
        this.add(new JLabel(new ImageIcon(bi)));
    }

    private void display() {
        JFrame f = new JFrame("RescaleOpTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new RescaleOpTest().display();
            }
        });
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜