Graphics オブジェクトに文字列を描画するために GDI+ を使用しています。
文字列を事前に定義された長方形の中に収めたい (線を壊さずに)
望ましいサイズが返されるまで、ループで TextRenderer.MeasureString() を使用する以外に、これを行う方法はありますか?
何かのようなもの:
DrawScaledString(Graphics g, string myString, Rectangle rect)
Graphics オブジェクトに文字列を描画するために GDI+ を使用しています。
文字列を事前に定義された長方形の中に収めたい (線を壊さずに)
望ましいサイズが返されるまで、ループで TextRenderer.MeasureString() を使用する以外に、これを行う方法はありますか?
何かのようなもの:
DrawScaledString(Graphics g, string myString, Rectangle rect)
ScaleTransform を使用できます
string testString = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse et nisl adipiscing nisl adipiscing ultricies in ac lacus.
Vivamus malesuada eros at est egestas varius tincidunt libero porttitor.
Pellentesque sollicitudin egestas augue, ac commodo felis ultricies sit amet.";
Bitmap bmp = new Bitmap(300, 300);
using (var graphics = Graphics.FromImage(bmp))
{
graphics.FillRectangle(Brushes.White, graphics.ClipBounds);
var stringSize = graphics.MeasureString(testString, this.Font);
var scale = bmp.Width / stringSize.Width;
if (scale < 1)
{
graphics.ScaleTransform(scale, scale);
}
graphics.DrawString(testString, this.Font, Brushes.Black, new PointF());
}
bmp.Save("lorem.png", System.Drawing.Imaging.ImageFormat.Png);
ただし、エイリアス効果が得られる場合があります。
編集:
しかし、代わりにフォント サイズを変更したい場合はscale
、スケール変換を使用する代わりに、上記のコードでフォント サイズを変更できると思います。両方を試して、結果の品質を比較してください。
この問題に対する別の解決策は次のとおりです。かなりの量のフォントの作成と破棄が必要なため、少し集中的ですが、状況とニーズによっては、より適切に機能する可能性があります。
public class RenderInBox
{
Rectangle box;
Form root;
Font font;
string text;
StringFormat format;
public RenderInBox(Rectangle box, Form root, string text, string fontFamily, int startFontSize = 150)
{
this.root = root;
this.box = box;
this.text = text;
Graphics graphics = root.CreateGraphics();
bool fits = false;
int size = startFontSize;
do
{
if (font != null)
font.Dispose();
font = new Font(fontFamily, size, FontStyle.Regular, GraphicsUnit.Pixel);
SizeF stringSize = graphics.MeasureString(text, font, box.Width, format);
fits = (stringSize.Height < box.Height);
size -= 2;
} while (!fits);
graphics.Dispose();
format = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
}
public void Render(Graphics graphics, Brush brush)
{
graphics.DrawString(text, font, brush, box, format);
}
}
これを使用するには、新しいクラスを作成して Render() を呼び出すだけです。これは、フォームへのレンダリング用に特別に記述されていることに注意してください。
var titleBox = new RenderInBox(new Rectangle(10, 10, 400, 100), thisForm, "This is my text it may be quite long", "Tahoma", 200);
titleBox.Render(myGraphics, Brushes.White);
RenderInBox オブジェクトは集中的に作成されるため、事前に作成する必要があります。したがって、すべてのニーズに適しているわけではありません。