问题
I am looking for a way to get the Bitwise XOR of two images on the command line(or in another way that can be implemented in a program or script).
This should result in the same final picture as using the XOR Blending mode in picture editors that support it (Paint.NET, Photoshop, etc)
As an example, say I have Image A:

and Image B:

then the result should look like:

The fun part of this is of course, that when you XOR image C with image B again, you will get an exact copy of image A.
Now, I have been looking all over the internet for a way to do this programmatically, but I have found nothing. Even ImageMagick does not support doing a bitwise XOR on images.
Does sombebody know a way to do this?
回答1:
ImageMagick can do it, although it's a bit convoluted. One way is:
convert img1 img2 -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out
(img1,img2,img_out are the two input and single output file names respectively).
Explanation
It's a bit ugly (I'm sure someone with more ImageMagick-fu than me could clean it up but it works like this:
-fx "xxx"basically says "perform the operationxxxon the image". In the expression above,uandvstand for the first and second input images respectively.Now,
-fxonly has bitwise AND&and bitwise OR|in the way of bitwise operators. To reconstruct bitwise XOR, we needconvert img1 img2 -fx "(u & NOT v) | (NOT u & v)" img_outTo get the
NOT(there is a logicalNOTbut no bitwiseNOT), we remember thatNOT x = 255-xifxis 8-bit. So to getNOT uwe can just do255-u, assuming imageuis 8-bit. Hence, the ImageMagick command would be:convert img1.png img2.img -fx "((255-u)&v)|(u&(255-v))" image_xor.pngThe one problem here is that when ImageMagick does
fxit normalises all the pixels inuandvin the range[0,1]instead of[0,255]as we expect, and doing bitwise on non-integers screws stuff up.Hence, we have to multiply all occurrences of
uandvin the above expression by 255 (so the bitwise operations work), and divide by 255 at the very end to get back in the range[0,1]that ImageMagick expects.
This gives us the original command,
convert img1 img2 -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out
Voila!
回答2:
I found a need for xor on an image and the G'MIC tool works for me. G'MIC is incredibly powerful, as is Image Magick, but worth a look for solving some tough image processing problems.
gmic a.png b.png -blend xor -o result.png
G'MIC also works directly on the images posted above.
gmic http://i.stack.imgur.com/Ws6e8.png http://i.stack.imgur.com/hoBIM.png -blend xor -o result.png
For help,
gmic -h -blend
回答3:
Here is how I would do in Java:
Iterate over all the pixels of the two images at once. (for loop (x) inside a for loop (y)). Of course, use a BufferedImage. You can get the color of the pixel by doing:
int color = img.getRGB(x, y);
Do the same for the other image as well and perform the xor operation on the two colors. Store the resulting value in a new BufferedImage with the same dimensions as the two input images.
Here is some sample code:
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;
}
To load an image from a file use:
BufferedImage imageA = ImageIO.read(new File("/home/username/image.png"));
回答4:
If you want to do yourself, do it pixel by pixel.
If you want a library, I recommend OpenCV. This is very nice and open source library with huge operations supported in image processing area. It supports direct XOR using ^ operator.
Good Luck.
回答5:
Knowing that
A XOR B = (A AND NOT B) OR (NOT A AND B).
and that most of common image processing tools do have and, or and not operations the rest is quite easy :)
Working in Python, you could have a simple script performing the operation and even adding it as a plugin in the gimp ;)
回答6:
OpenCV has all the logical operators on images and numpy images using bitwise_# Where # can be xor, and, and, not ... See OpenCV - Intersection between two binary images
来源:https://stackoverflow.com/questions/8504882/searching-for-a-way-to-do-bitwise-xor-on-images