Qqw*_*qwy 18 image imagemagick image-processing xor
我正在寻找一种在命令行上获得两个图像的Bitwise XOR的方法(或者以可以在程序或脚本中实现的另一种方式).
这应该导致与支持它的图片编辑器中使用XOR混合模式相同的最终图片(Paint.NET,Photoshop等)
举个例子,假设我有图像A:

和图像B:

那么结果应该是这样的:

当然,有趣的是,当您再次使用图像B对图像C进行异或时,您将获得图像A的精确副本.
现在,我一直在互联网上查找以编程方式执行此操作的方法,但我一无所获.甚至ImageMagick也不支持对图像进行按位异或.
sombebody知道这样做的方法吗?
mat*_*fee 23
ImageMagick可以做到这一点,虽然它有点复杂.一种方法是:
convert img1 img2 -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out
Run Code Online (Sandbox Code Playgroud)
(img1,img2,img_out分别是两个输入和单输出的文件名).
这有点难看(我敢肯定有人比我更多的ImageMagick-fu可以清理它,但它的工作原理如下:
-fx "xxx"基本上说" xxx对图像进行操作".在上面的表达,u并v分别代表第一和第二输入图像.
现在,-fx在按&位|运算符的方式中只有按位AND 和按位OR .要重建按位异或,我们需要
convert img1 img2 -fx "(u & NOT v) | (NOT u & v)" img_out
Run Code Online (Sandbox Code Playgroud)为了得到NOT(有一个逻辑NOT但没有按位NOT),我们记得NOT x = 255-x 如果 x是8位.所以NOT u我们可以做到255-u,假设图像u是8位.因此,ImageMagick命令将是:
convert img1.png img2.img -fx "((255-u)&v)|(u&(255-v))" image_xor.png
Run Code Online (Sandbox Code Playgroud)这里的一个问题是,当ImageMagick的做fx它在正常化的所有像素u和v范围内[0,1],而不是[0,255]像我们预期的,并且在非整数螺丝做按位东西了.
因此,我们必须将所有出现的u和v在上面的表达式中乘以255(因此按位运算起作用),并在最后除以255以回到[0,1]ImageMagick期望的范围内.
这给了我们原始命令,
convert img1 img2 -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out
Run Code Online (Sandbox Code Playgroud)
瞧!
Rob*_*abs 14
我发现需要xor一个图像,G'MIC工具适合我.G'MIC非常强大,Image Magick也是如此,但值得一试解决一些棘手的图像处理问题.
gmic a.png b.png -blend xor -o result.png
Run Code Online (Sandbox Code Playgroud)
G'MIC也直接在上面发布的图像上工作.
gmic http://i.stack.imgur.com/Ws6e8.png http://i.stack.imgur.com/hoBIM.png -blend xor -o result.png
Run Code Online (Sandbox Code Playgroud)
求助,
gmic -h -blend
Run Code Online (Sandbox Code Playgroud)
以下是我在Java中的表现:
一次迭代两个图像的所有像素.(for循环(y)中的循环(x)).当然,用一个BufferedImage.您可以通过执行以下操作获取像素的颜色:
int color = img.getRGB(x, y);
Run Code Online (Sandbox Code Playgroud)
对其他图像执行相同操作,并对两种颜色执行xor操作.将结果值存储在与两个输入图像具有相同尺寸的新BufferedImage中.
以下是一些示例代码:
public static BufferedImage xorEffect(BufferedImage imageA, BufferedImage imageB) {
if (imageA.getWidth() != imageB.getWidth() ||
imageA.getHeight() != imageB.getHeight())
{
throw new IllegalArgumentException("Dimensions are not the same!");
}
BufferedImage img = new BufferedImage(imageA.getWidth(),
imageA.getHeight(),
BufferedImage.TYPE_INT_ARGB_PRE);
for (int y = 0; y < imageA.getHeight(); ++y) {
for (int x = 0; x < imageA.getWidth(); ++x) {
int pixelA = imageA.getRGB(x, y);
int pixelB = imageB.getRGB(x, y);
int pixelXOR = pixelA ^ pixelB;
img.setRGB(x, y, pixelXOR);
}
}
return img;
}
Run Code Online (Sandbox Code Playgroud)
要从文件加载图像,请使用:
BufferedImage imageA = ImageIO.read(new File("/home/username/image.png"));
Run Code Online (Sandbox Code Playgroud)