Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing half of first pixel column after a Graphics Transform Scale

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?? Missing 1/2 pixel Graphics bug

Here is the original 10x10 8bpp image: 10x10 8bpp test 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;
    }
}
like image 292
Pedro77 Avatar asked Dec 25 '13 20:12

Pedro77


People also ask

What are the names of the very small squares that make up each image?

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.

What is a pixel in computer vision?

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.


1 Answers

Could it be related to PixelOffsetMode? This might be related to this other post. It has do with efficiency of rendering...

like image 76
J Trana Avatar answered Oct 21 '22 06:10

J Trana