C# Windows 印表機在 203dpi 模式下 要如何知道每種字型當選擇特定大小時 每個字印在紙張來會實際多寬和多高

C# Windows 印表機在 203dpi 模式下 要如何知道每種字型當選擇特定大小時 每個字印在紙張來會實際多寬和多高

C# Windows 印表機在 203dpi 模式下 要如何知道每種字型當選擇特定大小時 每個字印在紙張來會實際多寬和多高


資料來源: 數個AI+自己


C#線上編譯: https://dotnetfiddle.net/ [最後是用VS測試]


GitHub:https://github.com/jash-git/CS_PrintDocument_ThermalPrinter


code:[第二個MeasureStringInMm 效能高; 原理寫在第一個MeasureStringInMm]

public class DPI_Funs
{
    //---
    //DPI 相關函數
    //https://blog.csdn.net/wangnaisheng/article/details/139059374
    public static void GetScreenDpi(out float DpiX, out float DpiY)//系統DPI
    {
        //Dots Per Inch(每英寸點數): 意思是指每一英吋長度中,取樣或可顯示或輸出點的數目
        using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
        {
            DpiX = g.DpiX;
            DpiY = g.DpiY;
        }
    }
    public static float PixelsToInches(int pixels, float dpi)//像素 -> 英吋
    {
        return pixels / dpi;
    }
    public static float PixelsToMillimeters(int pixels, float dpi)//像素 -> 毫米
    {
        float inches = PixelsToInches(pixels, dpi);
        return inches * 25.4f;
    }
    public static int MillimetersToPixels(float millimeters, float dpi)//毫米 -> 像素
    {
        float inches = millimeters / 25.4f;
        return (int)(inches * dpi + 0.5f); // 使用0.5f进行四舍五入处理
    }

    //---
    // 計算在指定 DPI 下,字串所佔據的實際寬度與高度。
    public static SizeF MeasureStringInMm(string StrText, Font font, float fltDpi)//需要利用Dpi參數建一個虛擬畫布
    {
        // 檢查輸入是否有效,避免不必要的錯誤
        if (string.IsNullOrEmpty(StrText) || font == null || fltDpi <= 0)
        {
            return SizeF.Empty;
        }

        // 建立一個 1x1 像素的虛擬 Bitmap 作為測量畫布
        using (var bmp = new Bitmap(1, 1))
        {
            // 設定畫布的解析度為目標 DPI
            bmp.SetResolution(fltDpi, fltDpi);

            // 從畫布取得 Graphics 物件,此物件會繼承畫布的 DPI 設定
            using (var g = Graphics.FromImage(bmp))
            {
                // 1. 測量字串在指定 DPI 下的像素尺寸
                SizeF sizeInPixels = g.MeasureString(StrText, font);

                // 2. 將像素尺寸轉換為公釐 (mm)
                // 轉換公式: (像素 / DPI) * 25.4
                float fltWidthInMm = PixelsToMillimeters((int)sizeInPixels.Width, fltDpi);// (sizeInPixels.Width / fltDpi) * 25.4f;
                float fltHeightInMm = PixelsToMillimeters((int)sizeInPixels.Height, fltDpi);//(sizeInPixels.Height / fltDpi) * 25.4f;

                // 3.使用熱敏印表機實際測試落差手動校正
                fltWidthInMm -= 7;//在熱敏印表機實際測試得到參數
                fltHeightInMm -= 0;//雖然字型Size要-2會比較剛好,但是當字型變小文字又會太黏 所以最後還是不做調整

                // 4. 回傳包含公釐尺寸的 SizeF 物件
                return new SizeF(fltWidthInMm, fltHeightInMm);
            }
        }
    }

    public static SizeF MeasureStringInMm(string StrText, Font font, Graphics g)//傳入印表機映射的畫布來進行運算
    {
        // 檢查輸入是否有效,避免不必要的錯誤
        if (string.IsNullOrEmpty(StrText) || font == null || g == null)
        {
            return SizeF.Empty;
        }

        SizeF sizeInPixels = g.MeasureString(StrText, font);

        // 2. 將像素尺寸轉換為公釐 (mm)
        // 轉換公式: (像素 / DPI) * 25.4
        float fltWidthInMm = PixelsToMillimeters((int)sizeInPixels.Width, g.DpiX);//(sizeInPixels.Width / g.DpiX) * 25.4f;
        float fltHeightInMm = PixelsToMillimeters((int)sizeInPixels.Height, g.DpiX);//(sizeInPixels.Height / g.DpiY) * 25.4f;

        // 3.使用熱敏印表機實際測試落差手動校正
        fltWidthInMm -= 7;//在熱敏印表機實際測試得到參數
        fltHeightInMm -= 0;//雖然字型Size要-2會比較剛好,但是當字型變小文字又會太黏 所以最後還是不做調整

        // 4. 回傳包含公釐尺寸的 SizeF 物件
        return new SizeF(fltWidthInMm, fltHeightInMm);
    }
    //---計算在指定 DPI 下,字串所佔據的實際寬度與高度。

    //---DPI 相關函數
} 

One thought on “C# Windows 印表機在 203dpi 模式下 要如何知道每種字型當選擇特定大小時 每個字印在紙張來會實際多寬和多高

  1. C# Windows 印表機在 203dpi 模式下 要如何取得每種字型當選擇特定大小時 每個字印在紙張來會實際多寬和多高

    C# Windows 印表機在 203dpi 模式下 要如何抓取每種字型當選擇特定大小時 每個字印在紙張來會實際多寬和多高

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *