If I understand this question correctly, you have a bitmap (in memory, stored in a file, whatever) where the pixel data has been generated from some arbitrary binary source, per the answer given in the link you've provided. And you want to decode this pixel data, to retrieve the original binary data.
If so, then the following method will do what you want (where I've tried to adhere as much as possible to the original answer's conventions and structure):
private static byte[] DecodeBinaryFromBitmap(Stream inputStream)
{
using (Bitmap bitmap = (Bitmap)Image.FromStream(inputStream))
{
int length = bitmap.GetPixel(0, 0).ToArgb();
byte[] buffer = new byte[length];
int x = 1, y = 0;
for (var offset = 0; offset < buffer.Length; offset += 4)
{
var colorValue = bitmap.GetPixel(x, y);
byte[] pixelBuffer = BitConverter.GetBytes(colorValue.ToArgb());
Array.Copy(pixelBuffer, 0, buffer, offset, Math.Min(4, buffer.Length - offset));
x++;
if (x >= bitmap.Width)
{
x = 0;
y++;
}
}
return buffer;
}
}
This assumes you are using the ARGB version of the encoding routine in the other question. You pass a Stream
object that represents the bitmap data. This could be a FileStream
you've opened from a file on disk, or a MemoryStream
that was retrieved (for example) from a resource or database, or some other appropriate Stream
object you have.
I had intended to show a version that uses the LockBits()
method to get the raw byte data for the bitmap and decode from that, due to the fact that SetPixel()
and GetPixel()
are notoriously slow. But I tested this with a 1MB stream of random binary data and it only took about a quarter of a second to complete on my computer. I guess if you're trying to do this with really large data, say on the order of 1GB, then you might consider a faster approach. But if you're dealing with 10's of megabytes at the most (i.e. a few seconds worth of processing) and not having to do it very often, the above should be fine.
If you need it faster than that, then you should apply the basic technique but use LockBits()
to get at the bitmap data instead of calling GetPixel()
for each individual pixel. On the bright side, that would actually make the code simpler, because you don't need to do the conversion between the ARGB int
and the four bytes each pixel represents. The data will already be presented to you as bytes. The main downside is you'd have to worry about stride (but that's not terribly difficult).