在Java中,我试图在另一个BufferedImage中替换一个BufferedImage。
例如,可以替换为内的,因此会产生。
是否可以编写一个函数来替换另一个BufferedImage中的一个BufferedImage,并返回生成的BufferedImage?
public static BufferedImage replaceInsideBufferedImage(BufferedImage containingImage, BufferedImage toBeReplaced, BufferedImage replaceWithThis){
//In containingImage, replace all occurrences of toBeReplaced with replaceWithThis
}
答案 0 :(得分:1)
下面的方法可以解决问题。伪代码:
containingImage
的每个像素:
toBeReplaced
(逐个像素)
replaceWithThis
取代所有像素在找到所有模式后,最终会返回returnImage
。
replaceInsideBufferedImage()
代码:
public static BufferedImage replaceInsideBufferedImage(BufferedImage containingImage, BufferedImage toBeReplaced, BufferedImage replaceWithThis) {
BufferedImage returnImage = deepCopyImage(containingImage);
for (int x = 0; x+toBeReplaced.getWidth() < containingImage.getWidth(); x++) {
for (int y = 0; y+toBeReplaced.getHeight() < containingImage.getHeight(); y++) {
BufferedImage subImg = containingImage.getSubimage(x, y, toBeReplaced.getWidth(), toBeReplaced.getHeight());
if (imageEquals(subImg,toBeReplaced)) {
for (int sx = 0; sx < replaceWithThis.getWidth(); sx++) {
for (int sy = 0; sy < replaceWithThis.getHeight(); sy++) {
returnImage.setRGB(x+sx, y+sy, replaceWithThis.getRGB(sx, sy));
}
}
}
}
}
return returnImage;
}
完整的工作代码:
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import javax.imageio.ImageIO;
public class ReplacePattern {
public static void main(String[] args) throws Exception {
BufferedImage containingImage = ImageIO.read(new File("fourWhites.png"));
BufferedImage toBeReplaced = ImageIO.read(new File("oneWhite.png"));
BufferedImage replaceWithThis = ImageIO.read(new File("oneRed.png"));
BufferedImage replaced = replaceInsideBufferedImage(containingImage, toBeReplaced, replaceWithThis);
ImageIO.write(replaced, "png", new File("fourReds.png"));
}
public static BufferedImage replaceInsideBufferedImage(BufferedImage containingImage, BufferedImage toBeReplaced, BufferedImage replaceWithThis) {
BufferedImage returnImage = deepCopyImage(containingImage);
for (int x = 0; x+toBeReplaced.getWidth() < containingImage.getWidth(); x++) {
for (int y = 0; y+toBeReplaced.getHeight() < containingImage.getHeight(); y++) {
BufferedImage subImg = containingImage.getSubimage(x, y, toBeReplaced.getWidth(), toBeReplaced.getHeight());
if (imageEquals(subImg,toBeReplaced)) {
for (int sx = 0; sx < replaceWithThis.getWidth(); sx++) {
for (int sy = 0; sy < replaceWithThis.getHeight(); sy++) {
returnImage.setRGB(x+sx, y+sy, replaceWithThis.getRGB(sx, sy));
}
}
}
}
}
return returnImage;
}
// http://stackoverflow.com/a/3514297/1850609
public static BufferedImage deepCopyImage(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
// http://stackoverflow.com/a/11006474/1850609
private static boolean imageEquals(BufferedImage image1, BufferedImage image2) {
int width;
int height;
boolean imagesEqual = true;
if( image1.getWidth() == ( width = image2.getWidth() ) &&
image1.getHeight() == ( height = image2.getHeight() ) ){
for(int x = 0;imagesEqual == true && x < width; x++){
for(int y = 0;imagesEqual == true && y < height; y++){
if( image1.getRGB(x, y) != image2.getRGB(x, y) ){
imagesEqual = false;
}
}
}
}else{
imagesEqual = false;
}
return imagesEqual;
}
}
答案 1 :(得分:0)
有可能,但我不建议这样做。
检测图像是否存在于另一张图像中会非常慢。
此外,由于可能的编码伪像,可能永远不会在另一图像中检测到图像。在这种情况下,您将不得不实施更灵活的检测功能,这将需要更长的时间,并可能导致误报。
最有可能的是,您拥有从头开始重建图像的数据。不是对图像进行操作,而是简单地获取用于生成初始图像的数据,并基于它创建一个新图像。
但如果你真的需要这样做,你必须循环两个图像并比较像素。使用getRGB()
功能并逐个像素地比较图像。