java.lang.IllegalArgumentException:缩放常量的数量不等于颜色或颜色/alpha 分量的数量 [英] java.lang.IllegalArgumentException: Number of scaling constants does not equal the number of of color or color/alpha components
问题描述
我正在基于此示例编写 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 aJSlider
.
您引用的 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屋!