java.lang.IllegalArgumentException: количество констант масштабирования не равно количеству компонентов color или color / alpha - PullRequest
0 голосов
/ 30 апреля 2011

Я пишу 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: Количество констант масштабирования не равное количество цвета или цвет / альфа-компоненты

Чтобы быть более понятным ... Вот мой адаптированный класс тестового кода. Этот стиль кода выдает исключение ...

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

Я не совсем уверен, откуда исходит исключение, поэтому мне нужен ваш совет, где посмотреть?

P.S. Я полагаю, что это проблема IndexColorModel, но если это так, я не уверен, как это исправить ...

Любой полезный комментарий приветствуется:)

Andrew

1 Ответ

3 голосов
/ 30 апреля 2011

Используя приведенный ниже пример и предоставленное вами изображение , я не могу воспроизвести описанный вами эффект.

Я был озадачен, что BufferedImage из TYPE_4BYTE_ABGR_PRE имеет ComponentColorModel, в отличие от более привычного DirectColorModel, но это IndexColorModel, который не может быть изменен.

Приложение: обновлен код для использования filter(), так как предыдущая версия неправильно использовала BufferedImage.

Приложение: В другом ответе вы сказали,

Я не хочу каждый раз создавать новый BufferedImage. Я хочу отфильтровать изображение на лету, используя JSlider.

Приведенный вами пример делает это, создавая BufferedImage Once в конструкторе SeeThroughComponent и затем настраивая только RescaleOp в обработчике изменений ползунка. Это кажется довольно отзывчивым.

Приложение. В правке вашего вопроса вы упоминаете, что IllegalArgumentException может возникнуть при обнаружении изображения, имеющего IndexColorModel. Я могу воспроизвести это, используя, например, TYPE_BYTE_INDEXED. Вы можете обойти такие изображения, перехватив исключение и отобразив их отдельно, как показано здесь .

enter image description 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();
            }
        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...