Question

Today I wanted to try sth new in image processing in C#.

Szenario as following: I have two black and white images. Now I want to get all white pixels (x,y) from both images and put them into a return image. So in the end my image3 contains all white pixels from image1 and image2. I'm using unsafe pointers as they are faster.

So in the code I check if image1 in (x,y) == image2 in (x,y) as it is very unlikely that both pictures have a white pixel at the same spot

My approach right now:

private unsafe static Bitmap combine_img(Bitmap img1, Bitmap img2)
    {
        Bitmap retBitmap = img1;

        int width = img1.Width;
        int height = img1.Height;
        BitmapData image1 = retBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        BitmapData image2 = img2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // here an error

        byte* scan1 = (byte*)image1.Scan0.ToPointer();
        int stride1 = image1.Stride;

        byte* scan2 = (byte*)image2.Scan0.ToPointer();
        int stride2 = image2.Stride;

        for (int y = 0; y < height; y++)
        {
            byte* row1 = scan1 + (y * stride1);
            byte* row2 = scan2 + (y * stride2);

            for (int x = 0; x < width; x++)
            {
                if (row1[x] == row2[x])
                    row1[x] = 255;
            }
        }

        img1.UnlockBits(image1);
        img2.UnlockBits(image2);

        return retBitmap;
    }

unfortunately it returns an error when trying to lock the second image, saying the image has already been locked!

Was it helpful?

Solution

The problem was, that strangely I did pass the same image, here the corrected Code:

private unsafe static void combine_img(Bitmap img1, Bitmap img2)
    {
        BitmapData image1 = img1.LockBits(new Rectangle(0, 0, img1.Width, img1.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        BitmapData image2 = img2.LockBits(new Rectangle(0, 0, img2.Width, img2.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        int bytesPerPixel = 3;

        byte* scan1 = (byte*)image1.Scan0.ToPointer();
        int stride1 = image1.Stride;

        byte* scan2 = (byte*)image2.Scan0.ToPointer();
        int stride2 = image2.Stride;

        for (int y = 0; y < img1.Height; y++)
        {
            byte* row1 = scan1 + (y * stride1);
            byte* row2 = scan2 + (y * stride2);

            for (int x = 0; x < img1.Width; x++)
            {
                if (row2[x * bytesPerPixel] == 255)
                    row1[x * bytesPerPixel] = row1[x * bytesPerPixel - 1] = row1[x * bytesPerPixel-2] = 255;
            }
        }
        img1.UnlockBits(image1);
        img2.UnlockBits(image2);
    }

OTHER TIPS

I guess your second image is not 24 bit image. Mayber try something like:

BitmapData image2 = img2.LockBits(new Rectangle(0, 0, img2.Width, img2.Height), ImageLockMode.ReadWrite, img2.PixelFormat);

In this case you will always pass this line (I assume), but problem is you wont know you are actually dealing with 24 bits image or 32 bits image.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top