Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 使用.DrawString时字体显示太小或太大_Vb.net_Graphics_Fonts_Bitmap_Drawstring - Fatal编程技术网

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)