图像处理
不要使用 Graphics.DrawString
处理 Unicode 字符。
你应该改用 TextRenderer.DrawText
方法,例如:
TextRenderer.DrawText(e.Graphics, "こんにちは", this.Font,
new Point(10, 10), this.ForeColor, this.BackColor, flags);
缺点是您将无法指定一个
Brush
。
我已经测试过了。我认为还有其他问题,因为它在我的电脑上似乎可以工作。这是我的代码:
private void Form1_Paint(object sender, PaintEventArgs e)
{
var text = " །༉ᵒᵗᵗ͟ᵋༀ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟. . . ";
TextRenderer.DrawText(e.Graphics, "TextRenderer.DrawText" + text , this.Font,
new Point(10, 10), this.ForeColor, this.BackColor);
e.Graphics.DrawString("Graphics.DrawString" + text, this.Font,
new SolidBrush(this.ForeColor), new PointF(10, 30));
}
注意: 字体为 Arial Unicode MS 8.25pt
。
输出结果:
![文本绘制比较](https://istack.dev59.com/3NEbC.webp)
编码
这是原始字符串,以UTF-8存储:
[rotten4pple] །༉ᵒᵗᵗ͟ᵋༀ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟ ͟. . .
这是您获取的错误字符串,以Windows-1252存储:
[rotten4pple] à¼à¼‰áµ’ᵗᵗ͟ᵋༀ 🢠͟ ÍŸ ÍŸ ÍŸ ÍŸ ͟🢠͟ ÍŸ ÍŸ ÍŸ ÍŸ ÍŸ ͟🛠͟ ÍŸ ÍŸ ÍŸ ÍŸ ÍŸðŸ¢. . .
它们二进制相等。 这是两个字符串字节的十六进制表示:
5B 72 6F 74 74 65 6E 34 70 70 6C 65 5D 20 E0 BC
8D E0 BC 89 E1 B5 92 E1 B5 97 E1 B5 97 CD 9F E1
B5 8B E0 BC 80 EF A3 BF 20 F0 9F 90 A2 20 CD 9F
20 CD 9F 20 CD 9F 20 CD 9F 20 CD 9F 20 CD 9F F0
9F 90 A2 20 CD 9F 20 CD 9F 20 CD 9F 20 CD 9F 20
CD 9F 20 CD 9F 20 CD 9F F0 9F 90 9B 20 CD 9F 20
CD 9F 20 CD 9F 20 CD 9F 20 CD 9F 20 CD 9F F0 9F
90 A2 2E 20 2E 20 2E
由于这是二进制值的重新解释而不是重新编码,因此在.NET中使用Encoding.Convert
进行转换是不可行的。相反,您应该获取以错误编码方式表示的字符串的二进制表示,并直接将其作为正确编码读取:
var text = cmd.AllArguments
var bytes = Encoding.GetEncoding(1252).GetBytes(text)
text = Encoding.UTF8.GetString(bytes)
注意事项
您一直在询问API默认使用的编码方式。我不熟悉您正在使用的API,因此可能会受到机器配置的影响。您应该寻找一种重载方式,允许您指定接收UTF-8字符串。
有可能您实际上收到的是byte[]
,因此您可以直接在其上使用Encoding.UTF8.GetString
。如果无法指定编码,则应考虑切换为发送byte[]
,目的是更好地控制编码。
在这方面,不要使用Encoding.Default
,因为它将是机器语言的扩展ASCII码。
顺便说一句,UTF-8是网络传输的一个好选择,不仅因为它与语言和其他区域设置无关,还因为它与字节顺序(字节序)无关。