0

I have two 8bpp bitmaps. I want to do a bitwise AND of one to the other, but I don't see any obvious way to do this in .NET. Is it possible to do this without using non-.NET methods? Thanks!

user20493
  • 5,704
  • 7
  • 34
  • 31

4 Answers4

3

I think you're looking for Bitmap.LockBits.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • I may have to resort to this if I can't find a library method that does it. Unfortunately looping in C# probably will execute slower. – user20493 Feb 10 '10 at 16:51
3

You could try converting the Bitmap to a Byte array and then loop through the bytes anding them together

Edit : Ran a Time Test on the loop idea:

Example Code:

DateTime StartTime = DateTime.Now;
Image Image1 = Image.FromFile("C:\\Image1.bmp");
Image Image2 = Image.FromFile("C:\\Image2.bmp");
DateTime AfterLoad = DateTime.Now;
MemoryStream S = new MemoryStream();
Image1.Save(S, System.Drawing.Imaging.ImageFormat.Bmp);
Byte[] I1 = S.ToArray();
Image2.Save(S, System.Drawing.Imaging.ImageFormat.Bmp);
Byte[] I2 = S.ToArray();
DateTime AfterConvert = DateTime.Now;
DateTime AfterLoop = DateTime.Now;
if (I1.Length == I2.Length)
{
    Byte[] I3 = new Byte[I1.Length];
    for (int i = 0; i < I1.Length; i++)
        I3[i] = Convert.ToByte(I1[i] & I2[i]);
    AfterLoop = DateTime.Now;
    FileStream F = new FileStream("C:\\Users\\jamesb\\desktop\\Image3.bmp", FileMode.OpenOrCreate);
    F.Write(I3, 0, I3.Length);
    F.Close();
}
DateTime Finished = DateTime.Now;
MessageBox.Show("Load Time: " + (AfterLoad - StartTime).TotalMilliseconds.ToString() + " ms" + "\r\n" +
                "Convert Time: " + (AfterConvert - AfterLoad).TotalMilliseconds.ToString() + " ms"+ "\r\n" +
                "Loop Time: " + (AfterLoop - AfterConvert).TotalMilliseconds.ToString() + " ms"+ "\r\n" +
                "Save Time: " + (Finished - AfterLoop).TotalMilliseconds.ToString() + " ms"+ "\r\n" +
                "Total Time: " + (Finished - StartTime).TotalMilliseconds.ToString() + " ms");

with the following results :

Load Time: 30.003 ms
Convert Time: 94.0094 ms
Loop Time: 128.0128 ms
Save Time: 177.0177 ms
Total Time: 429.0429 ms

The images "Image1" and "Image2" were 4000 x 2250 (From a digital camera converted to 8 bit bmp)

James
  • 9,774
  • 5
  • 34
  • 58
1

If performance is not important, use Bitmap.GetPixel and Bitmap.SetPixel

Pavel Alexeev
  • 6,026
  • 4
  • 43
  • 51
1

You can use the 'BitBlt' function, in which you can AND the source and destination (SRCAND), the pinvoke signature is here.

Here is an article on Codeproject that uses a BitBlt wrapper here.

Hope this helps, Best regards, Tom.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • He asked to do it without using non-.NET methods. – Matthew Flaschen Feb 10 '10 at 16:39
  • @Matthew...unfortunately...there is a reliance on pinvoke to do some things that .NET cannot do.... – t0mm13b Feb 10 '10 at 16:43
  • There is no reason .NET can't do this. – Matthew Flaschen Feb 10 '10 at 16:45
  • @Matthew..is there a bitblt function in .NET? – t0mm13b Feb 10 '10 at 16:46
  • I was hoping for a .NET mechanism. But using BitBlt would probably be faster than anything I could do purely in .NET. I may end up using this. Thanks. – user20493 Feb 10 '10 at 16:55
  • The fact that there is no BitBit function in the .NET library does not mean the task can't be performed in .NET. – Matthew Flaschen Feb 10 '10 at 17:12
  • I tried it but the only raster ops that worked were WHITENESS and BLACKNESS. It might have been because one of the bitmaps I was using was an Aurigma bitmap (which handles the CMYK color space), which may not be 100% compatible with .NET bitmaps. – user20493 Feb 12 '10 at 14:23
  • alankdkd: check out this conversion http://stackoverflow.com/questions/1259711/is-it-possible-to-draw-a-shape-with-a-cmyk-colour-fill-in-net from cymk to rgb... – t0mm13b Feb 12 '10 at 14:37