Java重新着名BufferedImage不能处理更大高度的图像

问题描述 投票:1回答:1

我有一个程序,它应该采用图像的RGB值,然后将它们乘以一些常量,然后在JPanel上绘制新图像。问题是如果我的图像超过一定高度,特别是超过187像素,则新的彩色图像与高度小于187px的图像不同。

JPanel显示了这个:example

请注意较长的重新着色图像与较短的图像有何不同。我确信较短图像的颜色是正确的,我不知道它是如何弄乱的。

public class RecolorImage extends JPanel {
public static int scale = 3;

public static BufferedImage walk, walkRecolored;
public static BufferedImage shortWalk, shortWalkRecolored;

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setSize(200*scale, 400*scale);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new RecolorImage());

    walk = ImageLoader.loadImage("/playerWalk.png");
    walkRecolored = recolor(walk);  
    shortWalk = ImageLoader.loadImage("/playerWalkShort.png");
    shortWalkRecolored = recolor(shortWalk);

    frame.setVisible(true);
}

@Override
public void paint(Graphics graphics) {
    Graphics2D g = (Graphics2D) graphics;
    g.scale(scale, scale);  
    g.drawImage(walk, 10, 10, null);
    g.drawImage(walkRecolored, 40, 10, null);
    g.drawImage(shortWalk, 70, 10, null);
    g.drawImage(shortWalkRecolored, 100, 10, null);
}

重新着色方法:

public static BufferedImage recolor(BufferedImage image) {
    BufferedImage outputImage = deepCopy(image);

    for (int y = 0; y < image.getHeight(); y++) {
        for (int x = 0; x < image.getWidth(); x++) {

            int rgb = image.getRGB(x, y);
            Color c = new Color(rgb);

            int r = c.getRed();
            int g = c.getGreen();
            int b = c.getBlue();

            r *= 0.791;
            g *= 0.590;
            b *= 0.513;

            int newRGB = (rgb & 0xff000000) | (r << 16) | (g << 8) | b;
            outputImage.setRGB(x, y, newRGB);
        }
    }

    return outputImage;
}

如何加载图像并制作深层副本:

public static BufferedImage loadImage(String path) {
    try {
        return ImageIO.read(ImageLoader.class.getResource(path));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public static BufferedImage deepCopy(BufferedImage image) {
    ColorModel colorModel = image.getColorModel();
    boolean isAlphaPremultiplied = colorModel.isAlphaPremultiplied();
    WritableRaster raster = image.copyData(null);
    return new BufferedImage(colorModel, raster, isAlphaPremultiplied, null);
}

我的原始图像:tall imageshort image。谢谢你的帮助!

java rgb bufferedimage
1个回答
1
投票

您的源图像具有不同的颜色模型:

  • 短图像每像素使用4个字节(RGB和alpha)
  • 高图像每像素使用1个字节(索引到256色的调色板)

您重新着色的图像使用与源图像相同的颜色模型(由于deepCopy方法),因此高图像的重新着色图像也使用与源图像相同的调色板,这意味着它不能包含您想要的所有颜色。

由于您的重新着色代码会覆盖输出图像的每个像素,因此无需深度复制操作。相反,你最好像这样创建一个全彩色图像作为目标图像:

public static BufferedImage recolor(BufferedImage image) {
    BufferedImage outputImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
    //... code as before
}
© www.soinside.com 2019 - 2024. All rights reserved.