缺少第一像素列的一半图形变换后的量表 [英] Missing half of first pixel column after a Graphics Transform Scale

查看:102
本文介绍了缺少第一像素列的一半图形变换后的量表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,后一个图形上OnPaint事件变换缩放图像的第一像素列的一半不绘制



所有的代码所需重现它在帖子的末尾。基本上,我创建从PictureBox的派生的类名为PictureBox2和它覆盖OnPaint方法来执行缩放转换。这也改变了InterpolationMode以最近邻,以防止图形更改像素的样子。



PictureBox控件添加到一个名为Form6_GraphicsTest形式。控制扎根于各方。该PictureBox2背景色改为蓝色,表背颜色为深灰色。



正如你可以看到下面的图片,仅1/2图像的第一像素列被绘制。为什么?我失去了一些东西在这里?



下面是原来的10×10 8bpp图像:



编辑 - 解决方案
。对于某些 ODD 原因PixelOffsetMode.Default吃掉0.5个像素。解决方案:PixelOffsetMode.Half或高质量



代码PictureBox2.cs

 ; 
使用System.Drawing.Drawing2D;使用System.Windows.Forms的
;

命名空间GraphicsTest
{
公共类PictureBox2:图片框
{
公众的PointF变焦=新的PointF(20,20);
私人InterpolationMode interpolationMode = InterpolationMode.NearestNeighbor;

///<总结>
///绘制图像
///< /总结>
///< PARAM NAME =E>在绘画事件< /参数>
保护覆盖无效的OnPaint(PaintEventArgs的E)
{
如果(IsDisposed)
的回报;如果

(图片!= NULL)
{
如果(e.Graphics.InterpolationMode = interpolationMode!)
e.Graphics.InterpolationMode = interpolationMode;使用(矩阵变换= e.Graphics.Transform)
{
//e.Graphics.ResetTransform()

;

如果(Zoom.X = 1.0 || Zoom.Y = 1.0!)
transform.Scale(Zoom.X,Zoom.Y,MatrixOrder.Append);

//如果(ImageDisplayLocation.X!= 0 || ImageDisplayLocation.Y!= 0)//翻译转换回显示像素单元。
// transform.Translate(ImageDisplayLocation.X / Zoom.X,ImageDisplayLocation.Y / Zoom.Y);

e.Graphics.Transform =变换;
}
}

base.OnPaint(E);

//如果你想画过的东西在控制的控制协调,则必须先复位的转变! :D
//e.Graphics.ResetTransform();
//绘制你的东西
}
}
}

代码Form6_GraphicsTest.cs:

 使用系统; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Linq的;
使用System.Text;使用System.Windows.Forms的
;

命名空间GraphicsTest
{
公共类Form6_GraphicsTest:表
{
公共Form6_GraphicsTest()
{
的InitializeComponent();
BMP位图=新位图(@D:\Test 10x10.8bpp.png);
this.pictureBox21.Image = BMP;

this.pictureBox21.Zoom =新的PointF(20,20);

this.ClientSize =新的大小(Convert.ToInt32(this.pictureBox21.Zoom.X * bmp.Width)+ 30,Convert.ToInt32(this.pictureBox21.Zoom.Y * bmp.Height) + 30);
}

///<总结>
///必需的设计变量。
///< /总结>
私人System.ComponentModel.IContainer成分= NULL;

///<总结>使用
///清理的任何资源。
///< /总结>
///< PARAM NAME =处理>真要是托管资源应释放;否则为false< /参数>
保护覆盖无效的Dispose(BOOL处置)
{
如果(处置和放大器;及(成分= NULL)!)
{
components.Dispose();
}
base.Dispose(处置);
}

#region Windows窗体设计器生成的代码

///<总结>
///设计器支持所需的方法 - 不要修改
///此方法的代码编辑器的内容。
///< /总结>
私人无效的Ini​​tializeComponent()
{
this.pictureBox21 =新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 =新System.Drawing.Point(12,12);
this.pictureBox21.Name =pictureBox21;
this.pictureBox21.Size =新System.Drawing.Size(260,238);
this.pictureBox21.TabIndex = 0;
this.pictureBox21.TabStop = FALSE;
//
// Form6_GraphicsTest
//
this.AutoScaleDimensions =新System.Drawing.SizeF(6F,13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.ClientSize =新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(假);

}

#endregion

私人PictureBox2 pictureBox21;
}
}


解决方案

莫非它涉及到 PixelOffsetMode ?这可能与此有关的其他帖子。它做的渲染...


的效率

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;
    }
}

解决方案

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

这篇关于缺少第一像素列的一半图形变换后的量表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆