java 我尝试使用这个由克里斯托弗伊韦斯乘法复合效果,我不明白为什么我的数据类型类型类型_INT不符合所需的

e0bqpujr  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(91)

这是Kristopher Ives(Howto perform a MULTIPLY composite effect using Graphics2D)为乘法(叠加)效果创建的新Composite类。据我所知,他已经有一段时间没有活动了。每次我运行Main类时,我得到的都是"Expected integer sample type"异常,该异常在以下情况下抛出:

'(r.getSampleModel().getDataType() != DataBuffer.TYPE_INT)'
import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

public class MultiplyComposite implements Composite, CompositeContext {
    protected void checkRaster(Raster r) {
        if (r.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
            throw new IllegalStateException("Expected integer sample type");
        }
    }

    @Override
    public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
        checkRaster(src);
        checkRaster(dstIn);
        checkRaster(dstOut);

        int width = Math.min(src.getWidth(), dstIn.getWidth());
        int height = Math.min(src.getHeight(), dstIn.getHeight());
        int x, y;
        int[] srcPixels = new int[width];
        int[] dstPixels = new int[width];

        for (y=0; y < height; y++) {
            src.getDataElements(0, y, width, 1, srcPixels);
            dstIn.getDataElements(0, y, width, 1, dstPixels);

            for (x=0; x < width; x++) {
                dstPixels[x] = mixPixel(srcPixels[x], dstPixels[x]);
            }

            dstOut.setDataElements(0, y, width, 1, dstPixels);
        }
    }

    private static int mixPixel(int x, int y) {
        int xb = (x) & 0xFF;
        int yb = (y) & 0xFF;
        int b = (xb * yb) / 255;

        int xg = (x >> 8) & 0xFF;
        int yg = (y >> 8) & 0xFF;
        int g = (xg * yg) / 255;

        int xr = (x >> 16) & 0xFF;
        int yr = (y >> 16) & 0xFF;
        int r = (xr * yr) / 255;

        int xa = (x >> 24) & 0xFF;
        int ya = (y >> 24) & 0xFF;
        int a = Math.min(255, xa + ya);

        return (b) | (g << 8) | (r << 16) | (a << 24);
    }

    @Override
    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
        return this;
    }

    @Override
    public void dispose() {

    }

    public static final MultiplyComposite Multiply = new MultiplyComposite();

}

这是我混合两张BufferedImage类型的照片的代码。Overlay是从一个文件夹中提供的,并通过一个单独的方法转换为缓冲图像,你可以在底部找到,SS是由一个截图提供的,该截图通过另一个类运行,使其灰度化,然后转换为BufferedImage并返回(你也可以在底部找到)。
//将照片混合在一起

public static BufferedImage photosBlender(BufferedImage SS, BufferedImage Overlay) {
        try {
            BufferedImage base = SS;
            BufferedImage overlay = Overlay;

            Graphics2D g2d = base.createGraphics();
            g2d.setComposite(MultiplyComposite.Multiply);
            int x = (base.getWidth() - overlay.getWidth()) / 2;
            int y = (base.getHeight() - overlay.getHeight()) / 2;
            g2d.drawImage(overlay, x, y, null);
            g2d.dispose();

            File f = new File("resources/OutputImages/OutputBlended.png");
            ImageIO.write((RenderedImage) base, "png", f);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

获取叠加:通过用于选择在资源中提供的随机覆盖文件的随机选择方法来提供ARGS

public static BufferedImage OverlayProcess(String args) {
        BufferedImage OverlayInput = null;
        JFrame OverlayFrame = null;
        try {
            OverlayInput = ImageIO.read(new File(args));
            ImageIcon screenShotIcon = new ImageIcon(OverlayInput);
            
            //To Display selected Overlay for Testing purposes
            
            /*OverlayFrame = new JFrame();
            OverlayFrame.setLayout(new FlowLayout());
            OverlayFrame.setSize(1500, 800);
            JLabel lbl = new JLabel();
            lbl.setIcon(screenShotIcon);
            OverlayFrame.add(lbl);
            OverlayFrame.setVisible(true);
            OverlayFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);*/

        } catch (IOException e) {

        }

        return OverlayInput;

    }

SS的灰度化

public class GreyscaleTheImage {

    public static BufferedImage main(String args) throws IOException {
        BufferedImage img = null;
        File f = null;

        //read image
        try {
            f = new File(args);
            img = ImageIO.read(f);
        } catch (IOException e) {
            System.out.println(e);
        }

        //get image width and height
        int width = img.getWidth();
        int height = img.getHeight();

        //convert to grayscale
        int x = 0;
        int y;
        for (y = 0; y < height; y++) {
            for (x = 0; x < width; x++) {
                int p = img.getRGB(x, y);

                int a = (p >> 24) & 0xff;
                int r = (p >> 16) & 0xff;
                int g = (p >> 8) & 0xff;
                int b = p & 0xff;

                //calculate average
                int avg = (r + g + b) / 3;

                //replace RGB value with avg
                p = (a << 24) | (avg << 16) | (avg << 8) | avg;

                img.setRGB(x, y, p);
            }
        }

        BufferedImage finalImage = null;
        try {
            finalImage = img;
        } catch (Exception e) {
            System.out.println(e);
        }

        //write image
        try {
            f = new File("resources/OutputImages/Output.png");
            ImageIO.write(img, "png", f);
        } catch (IOException e) {
            System.out.println(e);
        }

        return finalImage;
    }//main() ends here

}//class ends here

我已经尝试过更改图像的栅格,但对于我目前的技能水平来说,这太多了。我根本不明白什么是sampleModel,也不明白DataType为3意味着什么。我怀疑这可能与图像可能具有32位"整数"缓冲区以外的其他内容有关(不管这意味着什么),因为克里斯托弗的资源说,这是所有它将工作。

dluptydi

dluptydi1#

我做了一个新的方法来将图像转换成ARGB,感谢Harald K在评论区留下的帮助。ARGB图像可以用我遇到问题的方法工作。

相关问题