Image is not drawn at the correct spot

You are loading an Image, then a copy of this source is created using:
Bitmap bitmap = new Bitmap();

When you create a copy of an Image this way, you sacrifice/alter some details:
Dpi Resolution: if not otherwise specified, the resolution is set to the UI resolution. 96 Dpi, as a standard; it might be different with different screen resolutions and scaling. The System in use also affects this value (Windows 7 and Windows 10 will probably/possibly provide different values)
PixelFormat: If not directly copied from the Image source or explicitly specified, the PixelFormat is set to PixelFormat.Format32bppArgb.

From what you were saying, you probably wanted something like this:

using (Bitmap imageSource = (Bitmap)Image.FromFile(@"[SomeImageOfLena]"))
using (Bitmap imageCopy = new Bitmap(imageSource.Width + 100, imageSource.Height, imageSource.PixelFormat))
{
    imageCopy.SetResolution(imageSource.HorizontalResolution, imageSource.VerticalResolution);
    using (Graphics g = Graphics.FromImage(imageCopy))
    {
        g.Clear(Color.Black);
        g.CompositingMode = CompositingMode.SourceCopy;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.DrawImage(imageSource, (imageCopy.Width - imageSource.Width) / 2, 0);
        pictureBox1.Image = (Image)imageSource.Clone();
        pictureBox2.Image = (Image)imageCopy.Clone();
    }
}

This is the result:
(The upper/lower frame black color is actually the Picturebox background color)

enter image description here

When the original Image Dpi Resolution is different from the base Dpi Resolution used when creating an Image copy with new Bitmap(), your results may be different from what is expected.

This is what happens with a source Image of 150, 96 and 72 Dpi in the same scenario:

enter image description here

Another important detail is the IDisposable nature of the Image object.
When you create one, you have to Dispose() of it; explicitly, calling the Dispose method, or implicitly, enclosing the Image contructor in a Using statement.

Also, possibly, don’t assign an Image object directly loaded from a FileStream.
GDI+ will lock the file, and you will not be able to copy, move or delete it.
With the file, all resources tied to the Images will also be locked.

Make a copy with new Bitmap() (if you don’t care of the above mentioned details), or with Image.Clone(), which will preserve the Image Dpi Resolution and PixelFormat.

Leave a Comment