Java重新着色BufferedImage无法与较大高度的图像一起使用

时间:2019-02-27 05:32:59

标签: java rgb bufferedimage

我有一个程序,该程序应该获取图像的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。感谢您的帮助!

1 个答案:

答案 0 :(得分: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
}