我正在尝试从源图像(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);
}
}
它将我的源像素更改为黑色和其他颜色,而不是白色。请告诉我,这里出了什么问题。
由于这是我的第一篇文章,我无法附上我的图片。抱歉给你带来不便。
编辑:我已在网站上传了源图像和输出图像。这是URL, 资料来源: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);
}
}
此致 拉加。
答案 0 :(得分: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调色板的最大尺寸。请注意,不应使用比图像中的颜色更大的调色板保存图像(特别是当您想稍后添加新颜色时)。您的原始文件可以使用双色调色板保存,节省762个字节。
请注意,将图像存储为索引,而不是使用相同数量的颜色的真彩色,您获得的收益并不高。原因是字节流(调色板=每像素1个字节,真彩色=每个像素3个或4个字节)无论如何都是无损压缩(使用DEFLATE)。索引可以节省几个字节(如果调色板很大,则会丢失几个字节),但它不会将文件大小减少到三分之一。