1

我正在尝试从我的源图像(PNG 格式)中替换一些像素。但我最终得到了一些令人困惑的结果。基本上我用黑色和白色替换特定的 RGB 值。这是我的代码,

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ChangePixel
{
public static void main(String args[]) throws IOException
{
    File file = new File(System.getProperty("user.dir"), "D4635.png");
    FileInputStream fis = new FileInputStream(file);
    BufferedImage image = ImageIO.read(fis);

    int[] replaceColors = new int[2];
    replaceColors[0] = Color.BLACK.getRGB();
    replaceColors[1] = Color.WHITE.getRGB();
    Color src = new Color(133, 101, 51);
    int srcRGBvalue = src.getRGB();

    changeAlg2(image, srcRGBvalue, replaceColors);
}

private static void changeAlg2(BufferedImage image, int srcRGBvalue, int[] replaceColors) throws IOException
{
    for (int width = 0; width < image.getWidth(); width++)
    {
        for (int height = 0; height < image.getHeight(); height++)
        {
            if (image.getRGB(width, height) == srcRGBvalue)
            {
                image.setRGB(width, height, ((width + height) % 2 == 0 ? replaceColors[0] : replaceColors[1]));
            }
        }
    }

    File file = new File(System.getProperty("user.dir"), "107.png");
    ImageIO.write(image, "png", file);
}
}

它将我的源像素更改为黑色和其他颜色,而不是白色。请告诉我,这里出了什么问题。

由于这是我的第一篇文章,我无法附上我的图片。带来不便敬请谅解。

编辑:我已经在站点中上传了源图像和输出图像。这是网址,来源:http ://s20.postimage.org/d7zdt7kwt/D4635.png 输出:http ://s20.postimage.org/kdr4vntzx/107.png 预期输出:黑色像素之后,白色像素有来。

编辑:根据Jan Dvorak的建议解决了代码,

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ChangePixel
{
public static void main(String args[]) throws IOException
{
    File file = new File(System.getProperty("user.dir"), "D12014.gif");
    FileInputStream fis = new FileInputStream(file);
    BufferedImage image = ImageIO.read(fis);

    Color src = new Color(223, 170, 66);
    int srcRGBvalue = src.getRGB();
    int[] replaceColors = new int[2];
    replaceColors[0] = Color.MAGENTA.getRGB();
    replaceColors[1] = Color.CYAN.getRGB();

    changeAlg2(image, srcRGBvalue, replaceColors);
}

private static void changeAlg2(BufferedImage image, int srcRGBvalue, int[] replaceColors) throws IOException
{
    BufferedImage image2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
    for (int width = 0; width < image.getWidth(); width++)
    {
        for (int height = 0; height < image.getHeight(); height++)
        {
            if (image.getRGB(width, height) == srcRGBvalue)
            {
                image2.setRGB(width, height, ((width + height) % 2 == 0 ? replaceColors[0] : replaceColors[1]));
            }
            else
            {
                image2.setRGB(width, height, image.getRGB(width, height));
            }
        }
    }

    File file = new File(System.getProperty("user.dir"), "110.gif");
    ImageIO.write(image2, "gif", file);
}
}

问候拉贾。

4

1 回答 1

1

由于您要添加原始图像调色板中不存在的颜色,因此您尝试设置的像素将被裁剪为调色板中最接近的颜色。您需要设置新的颜色模式。转换为 24bpp RGB(真彩色)或使用新颜色扩展调色板。

似乎无法修改现有BufferedImage ColorModel缓冲区或分配新缓冲区,但您可以创建一个新缓冲区并将数据复制到那里。BufferedImage用相同的方法创建一个新的也Raster可以(只有在位深度不变的情况下?)。

如果您不介意,您可以随时创建真彩色图像。尝试:

{
    BufferedImage old = image;
    image = new BufferedImage(
        old.getWidth(),
        old.getHeight(),
        BufferedImage.TYPE_INT_RGB
    );
    image.setData(old.getRaster());
} // old is no longer needed

API 参考:http ://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html

您可以尝试检测图像是否已经是真彩色 ( image.getColorModel() instanceof ???) 以避免在不需要时复制缓冲区。

您可以尝试扩展现有的调色板。如果这是不可能的(没有调色板开始或没有足够的空间),你必须回退到 RGB。

看:

http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html(getColorModel和构造函数采用 ColorModel 和类型)
http://docs.oracle.com/ javase/1.4.2/docs/api/java/awt/image/IndexColorModel.html(getMapSize、getRGBs和对应的构造函数)

从看到您的实际调色板,您将需要某种重复数据删除逻辑,因为您的调色板已经是 256 字节——PNG 调色板的最大大小。请注意,您不应使用比图像中的颜色更大的调色板来保存图像(尤其是当您想稍后添加新颜色时)。您的原始文件可以使用 2 色调色板保存,节省 762 字节。

请注意,将图像存储为索引而不是具有相同颜色数量的真彩色,您不会获得太多收益。原因是字节流(调色板 = 每像素 1 个字节,真彩色 = 每像素 3 或 4 个字节)无论如何都是无损压缩的(使用 DEFLATE)。索引可以为您节省几个字节(或丢失几个字节,如果调色板很大),但它不会将文件大小减少到三分之一。

于 2012-12-11T08:14:49.900 回答