Merge an image, a background and Text into a single image

与世无争的帅哥 提交于 2020-01-06 15:08:06

问题


I found this code here:

Private _BackgroundColours As New List(Of String)() From { _
    "339966", _
    "3366CC", _
    "CC33FF", _
    "FF5050" _
}

Public Function GenerateRactangle(firstName As String, lastName As String) As MemoryStream
    Dim imgSize() As Integer = {800, 800}
    Dim avatarString As String = String.Format("{0}{1}", firstName(0), lastName(0)).ToUpper()
    Dim bgColour = _BackgroundColours(New Random().[Next](0, _BackgroundColours.Count - 1))
    Dim bmp As Bitmap = New Bitmap(imgSize(0), imgSize(1))
    Dim sf As StringFormat = New StringFormat()
    Dim ms As MemoryStream = New MemoryStream()
    Dim font As Font = New Font("Arial", 172, FontStyle.Bold, GraphicsUnit.Pixel)
    Dim graphics__1 As Graphics = Nothing

    sf.Alignment = StringAlignment.Center
    sf.LineAlignment = StringAlignment.Center

    graphics__1 = Graphics.FromImage(bmp)
    graphics__1.Clear(DirectCast(New ColorConverter().ConvertFromString("#" + bgColour), Color))
    graphics__1.SmoothingMode = SmoothingMode.AntiAlias
    graphics__1.TextRenderingHint = TextRenderingHint.AntiAliasGridFit
    graphics__1.DrawString(avatarString, font, New SolidBrush(Color.WhiteSmoke), New RectangleF(0, 0, imgSize(0), imgSize(1)), sf)
    graphics__1.Flush()
    bmp.Save(ms, ImageFormat.Png)

    Return ms
End Function

On stackoverflow and it works great. However, I am in need of using a transparent PNG image in the background with the color changing background color.

What it currently looks like:

What I am looking for it to look like:

With the PNG image being this that was added:

I am hoping someone with more knowledge about the graphics calls can let me know how to go about doing this.


回答1:


The method you found leaves at least the Font and Grahics objects undisposed, so if that is used as a factory to process numerous images, it will leak. Things like picking a random back color might be better left to the calling code, and a memstream seems an odd return type choice.

A general method to create a background, overlay a PNG and apply the text to it:

Private Function CreateLabeledAvatar(av As Image, bg As Color, text As String) As Image

    ' fixed size?
    Dim bmp As New Bitmap(250, 250)
    Using g As Graphics = Graphics.FromImage(bmp)
        Using br As New SolidBrush(bg)
            g.FillRectangle(br, 0, 0, bmp.Width, bmp.Height)
        End Using
        g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
        g.CompositingQuality = CompositingQuality.HighQuality
        g.TextRenderingHint = TextRenderingHint.AntiAlias
        g.SmoothingMode = SmoothingMode.HighQuality
        g.DrawImage(av, 0, 0, bmp.Width, bmp.Height)

        ' lastly the text, centred on the new image
        ' could also draw to the AV passed to center on IT
        Using fnt As New Font("Arial", 32, FontStyle.Bold, GraphicsUnit.Pixel)
            TextRenderer.DrawText(g, text, fnt, New Rectangle(0, 0, 250, 250), 
                  Color.WhiteSmoke,
                  TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter)
        End Using

    End Using

    Return bmp
End Function

Sample usage:

Dim av = Image.FromFile("C:\temp\maleAV.png")
Dim bg = Color.FromArgb(62, 103, 207)

Dim newImg = CreateLabeledAvatar(av, bg, "BB")
pb1.Image = newImg

av.Dispose()

When your code is done with it, newImg should also be disposed.

There are other params you might want to be passed or set such as the desired size, font size and maybe even the text color. Passing any more, though and I would make it a class, so if it is used to processed a lot of them, many params could be set once.

Result:

The image created was 250,250, it is displayed in a 150x150 PBox



来源:https://stackoverflow.com/questions/36432056/merge-an-image-a-background-and-text-into-a-single-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!