java.lang.IllegalArgumentException:缩放常量的数量不等于颜色或颜色/alpha 分量的数量 [英] java.lang.IllegalArgumentException: Number of scaling constants does not equal the number of of color or color/alpha components

查看:25
本文介绍了java.lang.IllegalArgumentException:缩放常量的数量不等于颜色或颜色/alpha 分量的数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在基于此示例编写 aplha 复合测试应用程序

I am writing aplha composite test app based 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);

源链接:http://download.oracle.com/javase/tutorial/2d/images/drawimage.html

它适用于简单的图像,但对于照片(jpg 等),我得到以下异常:

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

java.lang.IllegalArgumentException:缩放常数的数量不等于颜色的数量或颜色/alpha 分量

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?

附言我想这是 IndexColorModel 问题,但如果是这样,我不知道如何解决它...

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 :)

安德鲁

推荐答案

使用下面的示例和 图像您提供的,我无法重现您描述的效果.

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

我很困惑TYPE_4BYTE_ABGR_PRE 的 >BufferedImage 有一个 ComponentColorModel,与更熟悉的DirectColorModel,但它是一个无法重新缩放的 IndexColorModel.

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.

附录:更新代码以使用 filter(),因为之前的版本错误地重用了 BufferedImage.

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

附录:在另一个答案中,你说,

Addendum: In another answer, you said,

我不想每次都创建一个新的 BufferedImage.我想使用 JSlider 动态过滤图像.

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

您引用的 example 是通过在 SeeThroughComponent 构造函数中创建 BufferedImage 一次,然后在滑块的更改处理程序中仅调整 RescaleOp.它似乎反应灵敏.

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.

附录:在对您问题的编辑中,您提到在遇到具有 IndexColorModel.我可以使用例如重现此内容TYPE_BYTE_INDEXED.您可以通过捕获异常并单独呈现它们来解决此类图像,如图 此处.

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.

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

这篇关于java.lang.IllegalArgumentException:缩放常量的数量不等于颜色或颜色/alpha 分量的数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆