如何绘制水印文本拼贴图像

时间:2013-07-06 14:33:57

标签: c# .net string draw

我想在图像上用C#.NET 4.5绘制文本字符串,并根据图块数计算文本位置。 让我们说1个瓷砖在中间绘制字符串,4个瓷砖在一行上绘制2个瓷砖等等......

如何计算任何给定瓷砖编号的文字位置?

enter image description here

我有这个我需要修改的功能:

private void DrawTiledWatermark(Graphics grPhoto, String strText, Font fnt, Brush brush, int nNumTiles)
    {
        StringFormat StrFormat = new StringFormat();
        StrFormat.Alignment = StringAlignment.Center;

        for (int nCurrentWatermark = 0; nCurrentWatermark < nNumTiles; nNumWatermarks++)
        {
            //Draw the m_Copyright string
            grPhoto.DrawString(strText,     //string of text
                fnt,                        //font
                brush,                      //Brush
                new PointF(x,y),  //How to calculate this Position ?
                StrFormat);
        }
    }

1 个答案:

答案 0 :(得分:2)

如我所见,你有两个问题:

  1. 获取文本的行数和列数
  2. 计算一个文本的大小
  3. 关于第一个问题,它有点数学。如果你有数字而你想把它拆分成行和列,你应该得到这个数字的所有除法,而不是你选择一些,将它们相乘,它是一个维度。第二个维度是原始数字除以此新数字。见例:

    • 我们将分组号码分成60到2 * 2 * 3 * 5
    • 现在我们为一个维度选择2 * 3 = 6
    • 第二维将是60/6 = 10
    • 我们的桌子将是6 x 10个单元格

    第二个问题由函数MeasureString(string s,Font f)解决。它是Graphics实例的方法,返回用这种字体写的字符串的大小。

    所以最终的代码如下所示:

    void DrawTextOnImage(Graphics grPhoto, string strText, Font font, Brush b, int num, Size imageSize)
    {
        //here we get dividers of our number
        int[] dividers = Dividers(num);
        //for first dimension I've choosen the biggest number, but you can change it
        int CountX = dividers[dividers.Length-1];
        //the secod dimension
        int CountY = num / CountX;
    
        //size of one text 
        int imageW = (int)grPhoto.MeasureString(strText, font).Width;
        int imageH = (int)grPhoto.MeasureString(strText, font).Height;
    
        //string format
        StringFormat StrFormat = new StringFormat();
        StrFormat.Alignment = StringAlignment.Center;
    
        //now when we knownumber of rows and columns and their size, we can start drawing
        for (int x = 0; x < CountX; x++)
        {
            for (int y = 0; y < CountY; y++)
            {
                PointF point = new PointF(      //position you want to know
                    (imageSize.Width - CountX * imageW) / 2 + (x * imageW),
                    (imageSize.Height - CountY * imageH) / 2 + (y * imageH)
                    );
                grPhoto.DrawString(strText,     //string of text
                font,                           //font
                b,                              //Brush
                point,                          //positio
                StrFormat);
            }
        }
    }
    
    int[] Dividers(int i)//get all dividers of number i
    {
        List<int> dividers = new List<int>();
        while (i > 1)
        {
            int div = NextDivider(i);
            dividers.Add(div);
            i = i / div;
        }
        return dividers.ToArray();
    }
    
    int NextDivider(int i)
    {
        if (i < 2) return i; //actualy it could be only value 1
        int div = 2;
        while (i % div != 0)
        {
            div++;
        }
        return div;
    }
    

    PS:对不起我的英语,我不是英语本地人,