If you consider the following image, it's a fairly basic icon, sized at 32x32. Around the icon is a transparent rectangle, although I filled in the four corners with a solid colour while testing.
Now consider this code, which simply draws the image, but at a larger scale:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel);
}
Note that I'm drawing the full image and I'm not attempting to crop it in any way, just enlarge it.
Finally, this is the output the test gives me:
Notice the problem? Half of the pixels in the top row and left column have vanished. If I then try and overlay a grid on top of this, it looks pretty awful as the grid is correctly aligned, but the image is not. Even just doubling the size to 64, 64 introduces this first row/column crop.
Note, I also tried offset the destination rectangle just in case it was drawing before 0,0, but this was not the case.
I also tried using different interpolation modes, but as far as I could tell through the headache inducing blur, the pixels were still cropped, so I don't believe it's due to the interpolation mode.
I also attempted using different graphics modes, but aside from the fact that it didn't seem to help, I need to stick with pixels anyway.
I tried again with a new copy of the image at 96dpi out of curiosity and got the same effect so I don't think it's the resolution of the source images.
Clutching at straws and using Rectangle
instead of RectangleF
also had no effect.
Can anyone offer any clues as to why this apparent crop is occurring?
Thanks;
The PixelOffsetMode
is set by default to PixelOffsetMode.Half
:
Specifies that pixels are offset by -.5 units, both horizontally and vertically, for high speed antialiasing.
In your case half a pixel in the original image is 8 pixels in the resulting image, which is exactly what you are missing.
Try setting it to PixelOffsetMode.None
PixelOffsetMode.HighQuality
:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel);
}
Just covering reply comfirmed by users, I tried it myself and the problem was solved with PixelOffsetMode.HighQuality
instead none
.
c#
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
my case c++ managed:
e->graphics->PixelOffsetMode = System::Drawing::Drawing2D::PixelOffsetMode::HighQuality;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With