C# realizes text drawing function

Ideas

This is the first time I write a blog. First, I will briefly describe the ideas.
1. First get the rgba of each pixel of the original image, and then create a new Bitmap with the same width and height as the original image
2. Set the background to white , And then set the font to be written to black
3. When the pixel is not white, replace the rgba of the current pixel of the newly created Bitmap with the rgba of the same pixel of the original image

Not much to say, just code

1. Get the rgba of each pixel in the original image

private List<List<Dictionary<string, byte>>> GetImageRgba(Image img)
        {
    
    

            var result = new List<List<Dictionary<string, byte>>>();
            
            Bitmap map = new Bitmap(img);
            for (int i = 0; i < map.Height; i++)
            {
    
    
                var rgbaList = new List<Dictionary<string, byte>>();
                for (int j = 0; j < map.Width; j++)
                {
    
    
                    //通过Bitmap 的 GetPixel(x,y)获取每个像素点的rgba
                    var color = map.GetPixel(j, i);
                    var rgbaDict = new Dictionary<string, byte>();
                    rgbaDict["r"] = color.R;
                    rgbaDict["g"] = color.G;
                    rgbaDict["b"] = color.B;
                    rgbaDict["a"] = color.A;
                    rgbaList.Add(rgbaDict);
                }
                result.Add(rgbaList);
            }
            
            return result;
        }

2. Generate the converted picture

1. First look at the declaration parameters of the method

/// <summary>
/// 生成最终图片
/// </summary>
/// <param name="content">原图每个像素点的rgba结果集</param>
/// <param name="str">要写入的文字</param>
/// <returns></returns>
private Image createImg(List<List<Dictionary<string, byte>>> content,string str)

2. Create a new Bitmap with the same width and height as the original image, and set the background to white

//原图高度
int height = content.Count();
//原图宽度
int width = content[0].Count();
//新建一个宽和高都为原始图片的bitmap
Bitmap map = new Bitmap(width, height);
//新建一个画板
Graphics g = Graphics.FromImage(map);
//设置画板的插补模式
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
//设置画板呈现质量
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清除整个绘画面并以指定背景色填充(白色背景)
g.Clear(ColorTranslator.FromHtml("#ffffff"));

3. Set the font size and use this to determine the number of rows and columns that the picture can write into the font

//14pt = 18.7px
//5pt = 6px
//7pt = 9px
Font font = new Font("宋体",7, FontStyle.Regular);
//字体高度
int fontH = font.Height;
//单个字体宽度
//7pt = 9px
float fontW = 9.0f;
//字体总宽度
fontW *= str.Length;

//每行最多可容纳多少个str字符
int rowNum = (int)((width - 0f) / fontW);
//行剩余像素点
int rowSyPx = (int)(width - rowNum * fontW);
//行str字符间隔 = 行剩余像素点/(行容纳数-1)
int rowJgPx = rowSyPx / (rowNum-1);
//列可容纳数
int columnNum = height / fontH;
//列剩余像素点
int columnSyPx = height % fontH;
//列间隔像素点 = 列剩余像素点/(列可容纳数-1)
float columnJgPx = (columnSyPx - 0f) / (columnNum-1);
            

4. Write the text into the new Bitmap

//将文字铺满图片
 //列容纳数 columnNum 外层for循环
 for (int i = 0; i < columnNum; i++)
 {
    
    
     //行容纳数 rowNum 内层for循环
     for (int j = 0; j < rowNum; j++)
     {
    
    
         //public void DrawString(string s, Font font, Brush brush, PointF point);
         //str为         要写入图片的文字
         //font为        要写入图片文字的字体大小和family
         //SolidBrush   字体的颜色(黑色)
         //PointF(x,y)  x坐标为 (str总宽度+行间隔宽度)*j  y坐标为 (str高度 + 列间隔宽度)*i
         g.DrawString(str, font, new SolidBrush(Color.Black), new PointF((rowJgPx + fontW)*j,(columnJgPx+fontH)*i));
     }
 }

5. When the pixel is not white, replace the rgba of the current pixel of the newly created Bitmap with the rgba of the same pixel of the original image.

//图片高度 为外层for循环
for (int i = 0; i < map.Height; i++)
{
    
    
    //图片宽度 为内层for循环
    for (int j = 0; j < map.Width; j++)
    {
    
    
        //获取原始图片的rbga Dictionary<string,byte>
        var rgba = content[i][j];
        //获取自绘图片的rgba 
        var newRgba = map.GetPixel(j, i);
        var R = newRgba.R;
        var G = newRgba.G;
        var B = newRgba.B;
        //因为背景为白色 字体为黑色 所以当像素点的r、g、b都为255时,即为白色时,continue,进入下一个像素点进行判断
        //若不为白色,即为当前像素点为文字时,将自绘图片的rgba替换为原图的rgba
        //此步骤较为耗时
        if (R == 255 && G == 255 && B == 255)
            continue;
        map.SetPixel(j, i, Color.FromArgb(rgba["a"], rgba["r"], rgba["g"], rgba["b"]));
        
    }
}

6. Convert Bitmap to Image

//然后通过Bitmap.Save(),将图片保存到stream中
//再通过Image.FromStream 将stream转换为Image作为结果return
 MemoryStream memoryStream = new MemoryStream();
 map.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
 return Image.FromStream(memoryStream);

Effect picture (the text in the picture is "I love you")

Original image:
Alt
Generated image:
Alt

to sum up

It is recommended not to be a code porter. I am a junior, and most of the knowledge involved is the knowledge of System.Drawing, so this function is not difficult to develop. It is not easy to develop, thank you.

Guess you like

Origin blog.csdn.net/MyLYuchun/article/details/109178885