.NET Core System.Drawing.Common 中文亂碼的坑
最近在寫一個漢字取點陣的程式,最開始是在win環境下執行的,沒發現什麼異常,然後今天把程式放在centos 下後發現英文正常,中文完全變成兩位的字了,最開始是字型的原因
在把宋體等安裝到centos 後發現中文出來了 但完全變了另外的字,然後使用第三方的ZKWeb.System.Drawing 執行程式,發現正常,但切換回System.Drawing.Common 就會完全不認識 或者完全變了字
比如 :我是中文
畫出來後變成了
這完全不是這個了,閱讀System.Drawing.Common的原始碼也並沒有發現其中的坑在哪裡 ,跟ZKWeb.System.Drawing 也對比了下,
找到關鍵性程式碼進行對比 System.Drawing.Common 中的原始碼
https://github.com/dotnet/corefx/blob/master/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs
[DllImport(LibraryName, ExactSpelling = true, CharSet = CharSet.Unicode)] internal static extern int GdipDrawString(HandleRef graphics, string textString, int length, HandleRef font, ref RectangleF layoutRect, HandleRef stringFormat, HandleRef brush);
以及ZKWeb.System.Drawing中的原始碼
https://github.com/zkweb-framework/ZKWeb.System.Drawing/blob/master/src/ZKWeb.System.Drawing/System.Drawing/gdipFunctions.cs
[DllImport(GdiPlus, CharSet=CharSet.Unicode)] static internal extern Status GdipDrawString (IntPtr graphics, string text, int len, IntPtr font, ref RectangleF rc, IntPtr format, IntPtr brush);
進行對比 並沒法發現什麼區別,於是就把這個定義放到自己的程式中定義 手動呼叫 GdipDrawString 看看是否會有中文亂碼的問題,然而發現換System.Drawing.Common中的定義或者ZKWeb.System.Drawing中的定義都可以正常顯示 但切換回System.Drawing.Common 使用系統的程式碼
Graphics.DrawString 中文就是不行,看了下DrawString 的程式碼也非常簡單 ,就是呼叫了GdipDrawString api 繪畫字串的,其原始碼如下
public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format) { if (brush == null) throw new ArgumentNullException(nameof(brush)); if (string.IsNullOrEmpty(s)) return; if (font == null) throw new ArgumentNullException(nameof(font)); CheckErrorStatus(Gdip.GdipDrawString( new HandleRef(this, NativeGraphics), s, s.Length, new HandleRef(font, font.NativeFont), ref layoutRectangle, new HandleRef(format, format?.nativeFormat ?? IntPtr.Zero), new HandleRef(brush, brush.NativeBrush))); }
也沒有發現什麼異常,最後使用反編譯檢視nuget包中的 System.Drawing.Common.dll 檔案,居然發現System.Drawing.Common.dll 中的GdipDrawString 居然少了CharSet 標記,判定是導致問題的所在,
於是懷疑是我沒有更新到最新版本導致的,上nuget一看發現是最新的版本 4.6的版本
於是估計是微軟沒更新導致的,暫時解決方法就是使用ZKWeb.System.Drawing 代替或者自己把這個api自己定義並拋棄系統的Graphics.DrawString 函式
&n