(Bitmap) behaves differently than the new bitmap (image)

Here is the test I wrote and which is currently failing:

var unusableColor = Color.FromArgb(13, 19, 20, 19);
var retrievedColor = Color.Empty;
var tempFile = Path.GetTempFileName();

using (var bitmap = new Bitmap(1, 1))
{
    bitmap.SetPixel(0, 0, unusableColor);
    bitmap.Save(tempFile, ImageFormat.Png);
}

using (var image = Image.FromFile(tempFile))
// This will lead to the error
using (var bitmap = new Bitmap(image))
// But this will work
//using (var bitmap = (Bitmap)image)
{
    retrievedColor = bitmap.GetPixel(0, 0);
}

Assert.That(retrievedColor, Is.SameAs(unusableColor));

If you look at retrievedColor, you will see that it will be the same as Color.FromArgb(13, 19, 19, 19). Thus, the difference will be that the green part has changed from 20 to 19.

Any idea why this is happening or under what circumstances the Bitmap constructor will change the pixel?

Update

This seems to be a deeper nested issue. Replacing the constructor with a Bitmapsimple conversion of the image variable, the problem disappears. Perhaps this solves the problem, but it does not explain. Moreover, I was able to reproduce the problem even in Paint.Net using the following procedure:

  • Open Paint.Net and create a new image (size does not matter)
  • (Ctrl + A)
  • (Del)
  • (F8)
  • RGB (19, 20, 19) (13).
  • (F)
  • (K)
  • -

, , , , Bitmap Image, , , , GDI + - .

2

, :

for (int a = 0; a < 256; a++)
{
    for (int r = 0; r < 256; r++)
    {
        for (int g = 0; g < 256; g++)
        {
            for (int b = 0; b < 256; b++)
            {
                using (var bitmap = new Bitmap(1, 1))
                {
                    var desiredColor = Color.FromArgb(a, r, g, b);
                    bitmap.SetPixel(0, 0, desiredColor);

                    // This will fail in a lot of colors with a low alpha channel value
                    using (var copiedBitmap = new Bitmap(bitmap))
                    // This will work, cause the information is entirely copied.
                    //using (var copiedBitmap = (Bitmap)bitmap.Clone())
                    {
                        var retrievedColor = copiedBitmap.GetPixel(0, 0);

                        if (desiredColor != retrievedColor)
                        {
                            Debug.Print(desiredColor + " != " + retrievedColor);
                        }
                    }
                }
            }
        }
    }

, , loonng, . , ( 1 10), , RGB .

, , Bitmap , . , -, GDI, Kernel - .Net.

, , , . , , (Bitmap)myBitmap.Clone() (Bitmap)Image.FromFile(filename) cause Image - , Bitmap.

+5
2

PNG, , Paint.NET, unusableColor.
:

using (Bitmap bitmap = (Bitmap)Image.FromFile(tempFile))
{
    retrievedColor = bitmap.GetPixel(0, 0);
}

+8

Clone: ​​

    using (var image = Image.FromFile(tempFile))
    {
        using (var bitmap = image.Clone() as Bitmap)
        {
            retrievedColor = bitmap.GetPixel(0, 0);
        }
    }

" ()", . , . , . default .

Bitmap:

Graphics graphics = null;
try
{
    graphics = Graphics.FromImage(this);
    graphics.Clear(Color.Transparent);
    graphics.DrawImage(original, 0, 0, width, height);
}
finally
{
    if (graphics != null)
    {
        graphics.Dispose();
    }
}

, , .

+2

All Articles