I have noticed that the half of the first pixel column of the image is not drawn after a Graphics Transform Scale on the OnPaint event.
All the code needed to reproduce it is at the end of the post. Basically I've created a Class derived from PictureBox called PictureBox2 and it overrides the OnPaint method to perform the Scale transformation. It also changes the InterpolationMode to NearestNeighbor to prevent Graphics from changing the pixels look.
The PictureBox control was added to a Form called Form6_GraphicsTest. The control is anchored in all sides. The PictureBox2 back color was changed to blue and the Form back color to dark grey.
As you can see on the image below, only 1/2 of the first pixel column of the image is drawn. Why?? Am I missing something here??
Here is the original 10x10 8bpp image:
EDIT - Solution For some ODD reason PixelOffsetMode.Default eats up 0.5 pixel. Solution: PixelOffsetMode.Half or HighQuality!
Code PictureBox2.cs
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace GraphicsTest
{
public class PictureBox2 : PictureBox
{
public PointF Zoom = new PointF(20, 20);
private InterpolationMode interpolationMode = InterpolationMode.NearestNeighbor;
/// <summary>
/// Paint the image
/// </summary>
/// <param name="e">The paint event</param>
protected override void OnPaint(PaintEventArgs e)
{
if (IsDisposed)
return;
if (Image != null)
{
if (e.Graphics.InterpolationMode != interpolationMode)
e.Graphics.InterpolationMode = interpolationMode;
using (Matrix transform = e.Graphics.Transform)
{
//e.Graphics.ResetTransform();
if (Zoom.X != 1.0 || Zoom.Y != 1.0)
transform.Scale(Zoom.X, Zoom.Y, MatrixOrder.Append);
//if (ImageDisplayLocation.X != 0 || ImageDisplayLocation.Y != 0) //Convert translation back to display pixel unit.
// transform.Translate(ImageDisplayLocation.X / Zoom.X, ImageDisplayLocation.Y / Zoom.Y);
e.Graphics.Transform = transform;
}
}
base.OnPaint(e);
//If you want to draw something over the control in control coordinate, you must first reset the transformation! :D
//e.Graphics.ResetTransform();
//Draw your stuff
}
}
}
Code Form6_GraphicsTest.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GraphicsTest
{
public class Form6_GraphicsTest : Form
{
public Form6_GraphicsTest()
{
InitializeComponent();
Bitmap bmp = new Bitmap(@"D:\Test 10x10.8bpp.png");
this.pictureBox21.Image = bmp;
this.pictureBox21.Zoom = new PointF(20,20);
this.ClientSize = new Size(Convert.ToInt32(this.pictureBox21.Zoom.X * bmp.Width) + 30, Convert.ToInt32(this.pictureBox21.Zoom.Y * bmp.Height) + 30);
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox21 = new GraphicsTest.PictureBox2();
((System.ComponentModel.ISupportInitialize)(this.pictureBox21)).BeginInit();
this.SuspendLayout();
//
// pictureBox21
//
this.pictureBox21.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBox21.BackColor = System.Drawing.SystemColors.Highlight;
this.pictureBox21.Location = new System.Drawing.Point(12, 12);
this.pictureBox21.Name = "pictureBox21";
this.pictureBox21.Size = new System.Drawing.Size(260, 238);
this.pictureBox21.TabIndex = 0;
this.pictureBox21.TabStop = false;
//
// Form6_GraphicsTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.pictureBox21);
this.Name = "Form6_GraphicsTest";
this.Text = "Form6_GraphicsTest";
((System.ComponentModel.ISupportInitialize)(this.pictureBox21)).EndInit();
this.ResumeLayout(false);
}
#endregion
private PictureBox2 pictureBox21;
}
}
In digital imaging, a pixel (abbreviated px), pel, or picture element is the smallest addressable element in a raster image, or the smallest addressable element in an all points addressable display device; so it is the smallest controllable element of a picture represented on the screen.
A pixel is what we call the color or light values that occupy a specific place in an image. Think of an image as a big grid, with each square in the grid containing one color or pixel. This grid is sometimes called a bitmap.
Could it be related to PixelOffsetMode? This might be related to this other post. It has do with efficiency of rendering...
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