-1

我想在 C# .NET 4.5 中在图像上绘制一个文本字符串,并根据图块的数量计算文本位置。假设 1 个瓷砖在中间绘制字符串,4 个瓷砖连续绘制 2 个瓷砖,依此类推......

如何计算任何给定图块编号的文本位置?

在此处输入图像描述

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

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);
        }
    }
4

1 回答 1

2

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

  1. 获取文本的行数和列数
  2. 计算一段文本的大小

关于第一个问题,它有点数学。如果你有数字并且你想把它分成行和列,你应该得到这个数字的所有除数,而不是你应该选择一些,将它们相乘,它是一维的。第二维是原始数字除以这个新数字。参见示例:

  • 我们可以将数字 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:对不起我的英语,我不是英语母语者

于 2013-07-06T20:25:27.203 回答