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

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

/* 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等),我得到这样的例外:

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

为了更清楚……这是我改编的测试代码类。 此代码样式抛出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 

我不太确定exception的来源,所以我需要你的建议去哪里看看?

PS我想这是IndexColorModel问题,但如果是这样,我不知道如何解决它…

任何有用的评论表示赞赏:)

安德鲁

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

我很困惑, TYPE_4BYTE_ABGR_PREBufferedImage有一个ComponentColorModel ,与更熟悉的DirectColorModel形成对比,但它是一个无法重新缩放的IndexColorModel

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

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

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

您引用的示例通过在SeeThroughComponent构造函数中创建一次 BufferedImage ,然后仅调整滑块的更改处理程序中的RescaleOp来实现此目的。 它看起来非常敏感。

附录:在对您的问题进行编辑时,您提到在遇到具有IndexColorModel的图像时可能会出现IllegalArgumentException 。 我可以使用,例如TYPE_BYTE_INDEXED重现这个。 您可以通过捕获exception并单独渲染它们来解决此类图像,如此处所示。

在此处输入图像描述

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