星期日, 1月 17, 2021

[C#] DesignerSerializationVisibilityAttribute

根據官方文章
來了解 DesignerSerializationVisibilityAttribute 用途,[DesignerSerializationVisibilityAttribute 序列化] 簡易白話說明,就是屬性視窗內 Property 設定完後,會不會儲存在 Designer.cs (下圖)

[C#] DesignerSerializationVisibilityAttribute-1

 
類型說明
Hidden程式碼產生器產生物件內容的程式碼,而非物件本身的程式碼
Visible程式碼產生器會產生物件的程式碼
Content程式碼產生器產生物件內容的程式碼,而非物件本身的程式碼

DesignerSerializationVisibilityAttribute 預設為 DesignerSerializationVisibility.Visible

星期一, 1月 11, 2021

HP M501 dn - 列印異常

使用者告知,印表機列印出紙紙張都會有條色塊在上面,且整體列印品質不良,如下圖
 
HP M501 dn-1

發現碳粉夾光鼓上有碳粉吸附在上方,用衛生紙清潔後,就恢復正常,下圖為擦拭過後

HP M501 dn-3

正常輸出

HP M501 dn-2

星期二, 1月 05, 2021

[C#] 繪製文字 - 測量

閱讀該篇 Graphics.MeasureString 方法 來了解如何測量文字,文章內的重點備註
The MeasureString method is designed for use with individual strings and includes a small amount of extra space before and after the string to allow for overhanging glyphs. Also, the DrawString method adjusts glyph points to optimize display quality and might display a string narrower than reported by MeasureString.
找到該篇 GDI+ Text, Resolution Independence, and Rendering Methods. Or - Why does my text look different in GDI+ and in GDI? 來閱讀,才了解上述文字要表達的意思
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;

namespace GraphicsSample
{
    public partial class FrmMeasureString : Form
    {
        public FrmMeasureString()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            MeasureStringMin(e);
        }

        private void MeasureStringMin(PaintEventArgs e)
        {
            string measureString = "文字寬度測量";
            Font stringFont = new Font("微軟正黑體", 16);

            // Figure1:MeasureString 前後會留些許空白
            SizeF stringSize = e.Graphics.MeasureString(measureString, stringFont);
            float stringSizeX = 80.0F;
            float stringSizeY = 10.0F;
            e.Graphics.DrawRectangle(Pens.Red, stringSizeX, stringSizeY, stringSize.Width, stringSize.Height);
            e.Graphics.DrawString(measureString, stringFont, Brushes.Black, stringSizeX, stringSizeY);

            // Figure2:MeasureString 搭配 StringFormat.GenericTypographic
            SizeF stringSizeFormat = e.Graphics.MeasureString(measureString, stringFont , int.MaxValue , StringFormat.GenericTypographic);
            float stringSizeFormatX = 80.0F;
            float stringSizeFormatY = 50.0F;
            e.Graphics.DrawRectangle(Pens.Red, stringSizeFormatX, stringSizeFormatY, stringSizeFormat.Width, stringSizeFormat.Height);
            e.Graphics.DrawString(measureString, stringFont, Brushes.Black, stringSizeFormatX , stringSizeFormatY);

            // Figure3:MeasureString 搭配 StringFormat.GenericTypographic + TextRenderingHint.AntiAlias
            e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
            SizeF stringSizeAntiAlias = e.Graphics.MeasureString(measureString, stringFont, int.MaxValue, StringFormat.GenericTypographic);
            float stringSizeAntiAliasX = 80.0F;
            float stringSizeAntiAliasY = 90.0F;
            e.Graphics.DrawRectangle(Pens.Red, stringSizeAntiAliasX, stringSizeAntiAliasY, stringSizeAntiAlias.Width, stringSizeAntiAlias.Height);
            e.Graphics.DrawString(measureString, stringFont, Brushes.Black, stringSizeAntiAliasX, stringSizeAntiAliasY);

            // Figure4:MeasureString 搭配 StringFormat.GenericTypographic + TextRenderingHint.AntiAliasGridFit
            e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            SizeF stringSizeAntiFit = e.Graphics.MeasureString(measureString, stringFont, int.MaxValue, StringFormat.GenericTypographic);
            float stringSizeAntiFitX = 80.0F;
            float stringSizeAntiFitY = 130.0F;
            e.Graphics.DrawRectangle(Pens.Red, stringSizeAntiFitX, stringSizeAntiFitY, stringSizeAntiFit.Width, stringSizeAntiFit.Height);
            e.Graphics.DrawString(measureString, stringFont, Brushes.Black, stringSizeAntiFitX, stringSizeAntiFitY);
        }
    }
}

星期六, 1月 02, 2021

[C#] 繪製線條、曲線 - 平滑化

參考該篇 - Antialiasing with Lines and Curves 的練習筆記,該文章內容 Aliasing 和 Antialiasing 說明是精華,擷取示意圖來筆記

[C#] 繪製線條、曲線 - 平滑化-1

SmoothingMode 有六種列舉,可以分為三類
 
類型說明
InvalidSpecifies an invalid mode.
None、Default、HighSpeedSpecifies no antialiasing.
AntiAlias、HighQualitySpecifies antialiased rendering.

有兩個平滑化情況,無法依靠 SmoothingMode 達到
C# 測試 Code
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace GraphicsSample
{
    public partial class FrmLineCurveAntialiAsing : Form
    {
        public FrmLineCurveAntialiAsing()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            int width = 100;
            int height = 50;

            using (Pen p = new Pen(Color.Red, 2))
            {
                e.Graphics.DrawEllipse(p, 10, 10, width, height);

                // 平滑化
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                e.Graphics.DrawEllipse(p, 130, 10, width, height);
            }
        }
    }
}
[C#] 繪製線條、曲線 - 平滑化-2

星期五, 1月 01, 2021

[C#] 繪製文字 - 平滑化

根據 How to: Use Antialiasing with Text 的練習筆記,反鋸齒 (平滑化) 是透過指定 TextRenderingHint 屬性,來提高文字外觀品質和可讀性

TextRenderingHint 有六種列舉,想要達到文字平滑化,基本上要指定 AntiAlias、AntiAliasGridFit、ClearTypeGridFit 這三種其中一種,ClearTypeGridFit 文字品質最佳,但效能最差,從 Understand font aliasing issues in C# 文章中可以理解到,不同字型可能會有不同測試結果,且小字型比較能看出差異

以下是使用微軟正黑體來觀察字型大小 6 和 16 文字平滑化差異
using System;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;

namespace GraphicsSample
{
    public partial class FrmTextAntialiAsingcs : Form
    {
        public FrmTextAntialiAsingcs()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            FontFamily fontFamily = new FontFamily("微軟正黑體");
            SolidBrush solidBrush = new SolidBrush(Color.FromArgb(255, 0, 0, 255));

            // 字型大小 6
            Font smallFont = new Font(fontFamily, 6, FontStyle.Regular, GraphicsUnit.Pixel);
            e.Graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
            e.Graphics.DrawString(nameof(TextRenderingHint.SingleBitPerPixel), smallFont, solidBrush, new PointF(10, 10));

            e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
            e.Graphics.DrawString(nameof(TextRenderingHint.AntiAlias), smallFont, solidBrush, new PointF(10, 60));

            e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            e.Graphics.DrawString(nameof(TextRenderingHint.ClearTypeGridFit), smallFont, solidBrush, new PointF(10, 110));

            // 字型大小 16
            Font bigFont = new Font(fontFamily, 16, FontStyle.Regular, GraphicsUnit.Pixel);
            e.Graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
            e.Graphics.DrawString(nameof(TextRenderingHint.SingleBitPerPixel), bigFont, solidBrush, new PointF(100, 10));

            e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
            e.Graphics.DrawString(nameof(TextRenderingHint.AntiAlias), bigFont, solidBrush, new PointF(100, 60));

            e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            e.Graphics.DrawString(nameof(TextRenderingHint.ClearTypeGridFit), bigFont, solidBrush, new PointF(100, 110));

        }
    }
}
程式執行後用放大鏡來觀察會比較有感