I need to XOR two BitmapData objects together.
I'm writing in Haxe, using the flash.* libraries and the AS3 compile target.
I've investigated HxSL and PixelBender, and neither one seems to have a bitwise XOR operator, nor do they have any other bitwise operators that could be used to create XOR (but am I missing something obvious? I'd accept any answer which gives a way to do a bitwise XOR using only the integer/float operators and functions available in HxSL or PixelBlender).
None of the predefined filters or shaders in Flash that I can find seem to be able to do a XOR of two images (but again, am I missing something obvious? Can XOR be done with a combination of other filters).
I can find nothing like a XOR drawmode for drawing things onto other things (but that doesn't mean it doesn't exist! That would work too, if it exists!)
The only way I can find at the moment is a pixel-by-pixel loop over the image, but this takes a couple of seconds per image even on a fast machine, as opposed to filters, which I use for my other image processing operations, which are about a hundred times faster.
Is there any faster method?
Edit:
Playing around with this a bit more I found that removing the conditional and extra Vector access in the loop speeds it up by about 100ms on my machine.
Here's the previous XOR loop:
Here is the updated XOR loop for the Vector solution:
Answer:
Here are the solutions that I've tested to XOR two images in Flash.
I found that the PixelBender solution is about 6-10 slower than doing it in straight ActionScript.
I don't know if it's because I have a slow algorithm or it's just the limits of trying to fake bitwise operations in PixelBender.
Results:
The clear winner is use
BitmapData.getVector()and then XOR the two streams of pixel data.1. PixelBender solution
This is how I implemented the bitwise XOR in PixelBender, based on the formula given on Wikipedia: http://en.wikipedia.org/wiki/Bitwise_operation#Mathematical_equivalents
Here is a Gist of the final PBK: https://gist.github.com/Coridyn/67a0ff75afaa0163f673
On my machine running an XOR on two 3200x1400 images this takes about 6500-6700ms.
I first converted the formula to JavaScript to check that it was correct:
Confirm that it's correct:
Then I converted the JavaScript to PixelBender by unrolling the loop using a series of macros:
XOR for each channel of the current pixel in the
evaluatePixelfunction:ActionScript Solutions
2. BitmapData.getVector()
I found the fastest solution is to extract a
Vectorof pixels from the two images and perform the XOR in ActionScript.For the same two 3200x1400 this takes about 480-500ms.
3. BitmapData.getPixel32()
Your current approach of looping over the BitmapData with
BitmapData.getPixel32()gave a similar speed of about 1200ms:4. BitmapData.getPixels()
My final test was to try iterating over two
ByteArrays of pixel data (very similar to theVectorsolution above). This implementation also took about 1200ms: