C# 查找以有限宽度渲染的最长初始子字符串

C# 查找以有限宽度渲染的最长初始子字符串,c#,.net,word-wrap,C#,.net,Word Wrap,我有一条长长的绳子,例如:“请帮我解决这个问题。” 此字符串太长,无法容纳100像素的宽度。 我需要得到这个字符串的子字符串,子字符串将适合100像素。子字符串“请帮助我解决问题”适合100像素 请帮助我如何估计这样的子字符串。谢谢 我的应用程序是Win Forms和C#。看起来您可以使用。看起来您可以使用。这应该可以。。。虽然没有真正的测试,也没有优化 var g = Graphics.FromImage(someimage); // or any from hwnd etc... shoul

我有一条长长的绳子,例如:“请帮我解决这个问题。” 此字符串太长,无法容纳100像素的宽度。 我需要得到这个字符串的子字符串,子字符串将适合100像素。子字符串“请帮助我解决问题”适合100像素

请帮助我如何估计这样的子字符串。谢谢


我的应用程序是Win Forms和C#。

看起来您可以使用。

看起来您可以使用。

这应该可以。。。虽然没有真正的测试,也没有优化

var g = Graphics.FromImage(someimage); // or any from hwnd etc... should use your panel/whatever
var f = new Font("YOURFONT", 12f, FontStyle.Regular, GraphicsUnit.Pixel); // replace with your vals
var yourtext = "yourtextyourtextyourtextyourtextyourtext";
while (g.MeasureString(yourtext, f).Width > 100)
    yourtext = yourtext.Remove(yourtext.Length - 2, 1);

这应该有用。。。虽然没有真正的测试,也没有优化

var g = Graphics.FromImage(someimage); // or any from hwnd etc... should use your panel/whatever
var f = new Font("YOURFONT", 12f, FontStyle.Regular, GraphicsUnit.Pixel); // replace with your vals
var yourtext = "yourtextyourtextyourtextyourtextyourtext";
while (g.MeasureString(yourtext, f).Width > 100)
    yourtext = yourtext.Remove(yourtext.Length - 2, 1);

如果您想要的只是一个好的估计值,那么您可以首先测量一个代表性字符串的宽度,以确定字体的平均字符宽度一次。一个好的代表可能不仅仅是字母表;您可以查找字符频率直方图以获得更好的平均宽度

string Representative = "abcdefghijklmnopqrstuvwxyz";
float CharacterWidth;

using(Bitmap b = new Bitmap(0, 0))
using(Graphics g = Graphics.FromImage(b))
using(Font f = /* some font definition */)
{
    CharacterWidth = g.MeasureString(Representative, f).Width / Representative.Length;
}
然后用它来估计N个像素内可以容纳多少个字符

string Text = ...

int DisplayWidth = 100;

int FitLength = Math.Min(Text.Length, (int)(DisplayWidth / CharacterWidth));
string FitText = Text.Substring(0, FitLength);

如果您想要的只是一个好的估计值,那么您可以首先测量一个代表性字符串的宽度,以确定字体的平均字符宽度一次。一个好的代表可能不仅仅是字母表;您可以查找字符频率直方图以获得更好的平均宽度

string Representative = "abcdefghijklmnopqrstuvwxyz";
float CharacterWidth;

using(Bitmap b = new Bitmap(0, 0))
using(Graphics g = Graphics.FromImage(b))
using(Font f = /* some font definition */)
{
    CharacterWidth = g.MeasureString(Representative, f).Width / Representative.Length;
}
然后用它来估计N个像素内可以容纳多少个字符

string Text = ...

int DisplayWidth = 100;

int FitLength = Math.Min(Text.Length, (int)(DisplayWidth / CharacterWidth));
string FitText = Text.Substring(0, FitLength);

与往常一样,Win32 API有一个专门为此设计的函数:


p/invoke声明:

与往常一样,Win32 API有一个专门为此设计的函数:



p/invoke声明:

我认为应该是g.MeasureString(yourtext…)而不是g.MeasureString(“yourtext”…
yourtext
不应该在while条件中引用。对于长度超过100个字符的字符串来说,这似乎会非常慢。@Lu-Lu-你是真的吗?它是(可能是)工作解决方案。有许多优化方案(例如,猜测字符的平均宽度,并在循环之前进行第一次传递子串)。做适合您需要的事情。这是“帮助我解决问题”,而不是“免费为我编写程序”。此外,运行此代码所需的时间微不足道,即使是在很长的字符串上。二进制搜索将帮助您快速找到最佳断点,即使是很长的字符串。我认为应该是g.MeasureString(yourtext…而不是g.MeasureString(“yourtext”…
yourtext
不应在while条件下被引用。对于长度超过100个字符的字符串,这似乎会非常慢。@Lu Lu-你是真的吗?这是一个(可能)可行的解决方案。有很多优化方法可供选择(例如,猜测字符的平均宽度,并在循环之前执行第一次传递子字符串)。做适合您需要的事情。这是“帮助我解决问题”而不是“免费为我编写程序”。此外,运行此代码的时间很短,即使是在很长的字符串上。二进制搜索将帮助您快速找到最佳断点,即使是很长的字符串。您是在部分信任环境中运行,还是可以调用非托管代码?@Lu-Lu:这里有3个好答案…你是在部分信任的环境中运行,还是可以调用非托管代码?@Lu-Lu:这里有3个好答案…@abatishchev:谢谢你的编辑,我不知道你可以用那种方式堆叠“using”语句。多么方便!@abatishchev:谢谢你的编辑,我不知道你可以堆叠以这种方式“使用”语句。多么方便!实际上它看起来像是
系统.Drawing.Graphics
类对于
度量值有类似的重载:确实如此。我们中的哪一位应该将该链接放在pinvoke.net页面上(在“等效托管API”下)?ooooooh.measurestring重载很好,从来没有注意到。好了,这个链接现在已经添加到pinvoke.net,为下一个考虑使用
GetTextExtentExPoint
的人节省时间。实际上,它看起来像
系统。Drawing.Graphics
类对
measurestring
有类似的重载:它确实如此。Whi我们中的一个应该把这个链接放在pinvoke.net页面上(在“等效托管API”下)?ooooooh.Nice在measurestring重载上,从未注意到。好的,这个链接现在已经添加到pinvoke.net,为下一个想从.net使用
GetTextExtentExPoint
的人节省时间