Question

I'm writing a program that removes an overlay from a png image using the mask (the overlay image)

having image 1 and 2 I want to achive image 3.

I have tried using lockbits and tried many things but I can't do the math right I think

rgbValues is the byte array of overlay and rgbValues2 is the byte array of given image.

for (int counter = 0; counter < rgbValues.Length; counter ++)
            {
                int x = (counter / 4) * 4;
                if (rgbValues[x + 3] != 0)
                {
                    if (rgbValues[x + 3] == rgbValues2[x + 3])
                    {
                        rgbValues2[counter] = 0;
                    }
                    else
                    {
                        float a1 = (float)rgbValues[counter];
                        float a2 = (float)rgbValues2[counter] ;
                        float b1 = (float)rgbValues[x + 3];
                        float b2 = (float)rgbValues2[x + 3];
                        rgbValues2[counter] = (byte)(2 * a2- a1);
                    }
                }
            }

enter image description here

Was it helpful?

Solution

I've tried this with your sample Images, although they are composed in the same big image and looks like it works. The following code doesn't use LockBits for simplicity, it just gives you the idea, that is how to calculate the base color (in the third image) from the blend color (in the second image) and the result color (in the first image):

public Image ExtractBaseImage(Bitmap resultImage, Bitmap blendImage) {
    Bitmap bm = new Bitmap(resultImage.Width, resultImage.Height);
    for (int i = 0; i < resultImage.Width; i++) {
        for (int j = 0; j < resultImage.Height; j++) {
           Color resultColor = resultImage.GetPixel(i, j);
           Color blendColor = blendImage.GetPixel(i, j);
           if (blendColor.A == 0) bm.SetPixel(i, j, resultColor);
           else if(blendColor != resultColor){
              float opacity = blendColor.A / 255f;
              int r = Math.Max(0,Math.Min(255,(int) ((resultColor.R - (opacity) * blendColor.R) / (1-opacity))));
              int g = Math.Max(0,Math.Min(255,(int)((resultColor.G - (opacity) * blendColor.G) / (1-opacity))));
              int b = Math.Max(0,Math.Min(255,(int)((resultColor.B - (opacity) * blendColor.B) / (1-opacity))));                        
              bm.SetPixel(i,j,Color.FromArgb(r,g,b));
           }
        }
    }
    return bm;
}

Usage: Suppose the images are numbered as you did to the images posted in your question, we have image1, image2, image3 variables:

image3 = ExtractBaseImage((Bitmap)image1, (Bitmap)image2);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top