Vb.net 使用.DrawString时字体显示太小或太大
我需要在图像底部添加半英寸的空白,并在左下角和右下角(在新添加的空白内)绘制一条字符串。一切似乎都很好,但字体有时显得太小或太大 我想我需要以某种方式将抽绳字体缩放到图像的大小?我已经筋疲力尽了,想弄明白这一点。。。请帮忙 请参阅下面的代码----Vb.net 使用.DrawString时字体显示太小或太大,vb.net,graphics,fonts,bitmap,drawstring,Vb.net,Graphics,Fonts,Bitmap,Drawstring,我需要在图像底部添加半英寸的空白,并在左下角和右下角(在新添加的空白内)绘制一条字符串。一切似乎都很好,但字体有时显得太小或太大 我想我需要以某种方式将抽绳字体缩放到图像的大小?我已经筋疲力尽了,想弄明白这一点。。。请帮忙 请参阅下面的代码---- 当您即将知道这一行的bates字符串的大小(宽度)时: Dim textSize As SizeF = gr.MeasureString(bates, mfont) 在位图上绘制字符串之前,您必须计算要对字体大小执行的缩放,以确保文本缩小(
当您即将知道这一行的
bates
字符串的大小(宽度)时:
Dim textSize As SizeF = gr.MeasureString(bates, mfont)
在位图上绘制字符串之前,您必须计算要对字体大小执行的缩放,以确保文本缩小(如果太长)或拉伸(如果太窄),同时不会在图像上过度拉伸
然后,只有当您拥有有效的字体大小时,才能像使用以下行一样绘制文本
gr.DrawString(bates, mfont, Brushes.Black, bm.Width - textSize.Width - hoffset, newBitmap.Height - voffset)
gr.DrawString(designation, mfont, Brushes.Black, hoffset, newBitmap.Height - voffset)
要知道要使用的正确字体大小,请查看。
我知道这是C#,但这基本上是你在画贝茨和命名文字之前要做的。区别在于两点:
- 您有两个
字符串
可在剪辑矩形中缩放(贝茨和名称),而不是一个
- 您必须考虑左侧的
指定
和右侧的bates
之间的(默认)分隔
但这两点很容易解决。这也意味着你的问题可能是重复的(StackOverflow不推荐同一个问题的多个变体,因为SO的目的是将你直接带到一个页面,询问一个问题及其答案(如果回答了的话),而不是向你大量提供同一主题的几十份副本)
但是,这两个字符串(指定和贝茨)就足以将其视为一个新问题,因为代码处理不被其他主题所覆盖。
下面是转化为vb.Net的saeed函数
Private Function FindFont( _
ByRef rg As Graphics, _
ByVal testString as String, _
ByVal clipRoom As Size, _
ByVal preferedFont As Font) As Font
' You should perform some scale functions...
Dim realSize As SizeF = rg.MeasureString(testString, PreferedFont)
Dim heightScaleRatio As Double = clipRoom.Height / realSize.Height
Dim widthScaleRatio As Double = clipRoom.Width / realSize.Width
Dim scaleRatio As Double
Dim newFontSize As Single ' I'm used to declare everything on top.
If heightScaleRatio < widthScaleRatio Then
scaleRatio = heightScaleRatio
Else
scaleRatio = widthScaleRatio
End If
newFontSize = CSng(preferedFont.Size * ScaleRatio)
Return New Font(preferedFont.FontFamily, newFontSize, preferedFont.Style)
End Function
stampSeparation是一个仲裁变量,表示中的宽度
在指定和指定之间的像素。基本上,它看起来是这样的:
您在底部的房间是一个截然不同的故事:您的AddBorderAndStamp
函数有一个borderWidthInPixels
(作为整数)参数,用于定义您在顶部/底部添加的房间。然后使用voffset
(作为整数)变量向上移动戳记。。这意味着您要打印文本的图像底部可用空间的高度为:
clipRoom.Height = vOffset ' ?
' 75 ?
' (CAREFULL !!! clipRoom.Height MUST be positive !!!)
如果我是你,我会根据AddBorderAndStamp
的一小部分动态定义clipRoom.Height
,并在MeasureString
知道designation
和bates
高度的最终高度后动态计算vOffset
。。。但那太过分了
' perhaps one simple logic like the following would suffice
' clipRoom.Height = CInt(vOffset * 4 / 5)
现在您有了clipRoom
以及调用FindFont(…)
函数所需的所有其他内容
因此:
顺便说一下:
你好。您应该在帖子中添加[vb.Net]
标记,然后删除
[image]
或[bitmap]
,因为它们是同义词
如果没有格式,很难发现代码错误。但既然你是StackOverflow的新手(所以),我不想否决你或给你打旗号,但我坚持:更新你问题的标签
备注1:
' you've set newBitmap to have
' bm.Heigth expanded by two times the value of borderWidthInPixels
Dim newBitmap As New Bitmap(bm.Width, bm.Height + (borderWidthInPixels * 2))
' ...
' Then you plot bm at the very top of newBitmap
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' that means you have a blank space at the bottom
' that height twice the value of borderWidthInPixels
' ...
' But you plot bates and designation
' at a fixed vOffset from the bottom of newBitmap
gr.DrawString(bates, , , , newBitmap.Height - voffset)
gr.DrawString(designation, , , , newBitmap.Height - voffset)
你写道:
For x As Integer = 0 To newBitmap.Width - 1
For y As Integer = newBitmap.Height - 1 To (newBitmap.Height - 1) - borderWidthInPixels Step -1
newBitmap.SetPixel(x, y, borderColor)
Next
Next
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
您正在从底部逐像素更改newBitmap
的颜色。我同意这一点,但有更好的方法来实现这一点
但是,您要声明一个图形来处理newBitmap上的图形,然后调用gr.Clear(Color.White)
??
难道这不应该完全用白色绘制你的新位图,从而破坏上面SetPixel循环的目的吗
我不明白。也许你想让这个函数浪费时间,所以就用它吧
System.Threading.Thread.Sleep(X) ' where X is an Integer variable in miliseconds
否则,我建议您去掉SetPixel及其循环编码,只使用gr图形填充矩形:
' ...
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
gr.FillRectangle( _
New SolidBrush(borderColor), _
0, newBitmap.Height - borderWidthInPixels, _
newBitmap.Width, borderWidthInPixels)
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' ...
备注2:
' you've set newBitmap to have
' bm.Heigth expanded by two times the value of borderWidthInPixels
Dim newBitmap As New Bitmap(bm.Width, bm.Height + (borderWidthInPixels * 2))
' ...
' Then you plot bm at the very top of newBitmap
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' that means you have a blank space at the bottom
' that height twice the value of borderWidthInPixels
' ...
' But you plot bates and designation
' at a fixed vOffset from the bottom of newBitmap
gr.DrawString(bates, , , , newBitmap.Height - voffset)
gr.DrawString(designation, , , , newBitmap.Height - voffset)
我不清楚borderWidthInPixels
和voffset
之间的关系,这可能会误导上述clipRoom.Height
的表述
然而,我认为我已经提供了足够的材料让你达到你想要的地方,即使上面的clipRoom.Height公式是错误的,也很容易修复它
您还必须了解,默认情况下,我使用了saeed方法,但通过阅读我链接的帖子,您会发现其他方法,迭代方法,我不太喜欢,因为它们是CPU密集型迭代,但并不总是更精确。你甚至可以找到关于TextToBitmap的提示;如果更适合你,试一下,但也更复杂。。对于你正在做的事情,我认为一个或两个像素位移输出不是问题
对于垂直放置,您说“.但是字体有时显得太小或太大…”这不够精确,无法全面了解问题。你应该已经发布了“太小”案例和“太大”案例的两张图片样本。由于您没有在代码中更改字体大小,我认为太小的问题是指定和bates之间的空间太大,而太大的问题是重叠文本。这里没有一个提到可能的垂直布局问题,所以我的回答没有详细说明这一方面。这就是为什么我不在这里介绍多行逻辑,这将代表另一个问题(如果没有可用的话)Hello。您应该在文章中添加vb.Net标记,并删除图像或位图,因为它们是同义词。
For x As Integer = 0 To newBitmap.Width - 1
For y As Integer = newBitmap.Height - 1 To (newBitmap.Height - 1) - borderWidthInPixels Step -1
newBitmap.SetPixel(x, y, borderColor)
Next
Next
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
System.Threading.Thread.Sleep(X) ' where X is an Integer variable in miliseconds
' ...
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
gr.FillRectangle( _
New SolidBrush(borderColor), _
0, newBitmap.Height - borderWidthInPixels, _
newBitmap.Width, borderWidthInPixels)
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' ...
' you've set newBitmap to have
' bm.Heigth expanded by two times the value of borderWidthInPixels
Dim newBitmap As New Bitmap(bm.Width, bm.Height + (borderWidthInPixels * 2))
' ...
' Then you plot bm at the very top of newBitmap
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' that means you have a blank space at the bottom
' that height twice the value of borderWidthInPixels
' ...
' But you plot bates and designation
' at a fixed vOffset from the bottom of newBitmap
gr.DrawString(bates, , , , newBitmap.Height - voffset)
gr.DrawString(designation, , , , newBitmap.Height - voffset)