C # повернутый DrawString из правого угла - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь нарисовать текст на изображении от верхнего правого угла к нижнему левому углу.Мой код испортил расположение кулис.пока этот код рисует вот так, но мне нужна помощь, чтобы нарисовать текст между этими красными линиями.

enter image description here

string img_src = "F:\\blank_imge.jpg";
    System.Drawing.Image selected_img = System.Drawing.Image.FromFile(img_src);
    using(Graphics gr = Graphics.FromImage(selected_img))
    {
        Font font = new Font("Arial", 2.0f);
        int x = selected_img.Width;
        int y = 0;
        for (int b = 1; b <= 5; b++)
        {
             GraphicsState state = gr.Save();
             gr.ResetTransform();
             int opacity = 35;
             string txt = "watermark";
             using (Brush brush = new SolidBrush(Color.FromArgb(opacity, 255, 255, 255)))
             {
                   SizeF textSize = gr.MeasureString("watermark", font);
                   gr.RotateTransform(45);
                   gr.SmoothingMode = SmoothingMode.HighQuality;
                   gr.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                   gr.DrawString(txt, font, brush, new PointF(x - textSize.Width, y));
             }

             y = y + 25;
             gr.Restore(state);
        }    
       selected_img.Save("F:\\watermarked.jpg");
    }

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Похоже, что в вашем вопросе есть как минимум два подвопроса:

  • Нарисуйте по диагонали : ваш пример показывает, что вы хотите написать каждую строку текста перпендикулярнодо вторичной диагонали, так что я пойду с этим.
  • Я предположил, что мы говорим о прямоугольниках, поэтому 45-градусная часть просто глупа, добавлен код для вычисления реального угла
  • Рисуем внутри полосы Я не знаю, еслиВаша проблема заключается в позиционировании или сохранении ширины строки в границах.

Приведенный ниже код обращается к Рисование по диагонали , чтобы правильно позиционировать деталь.На мой взгляд, проще поместить вещи в «полосу» (вам нужно перебирать g.MeasureString до тех пор, пока все не уместится или не обернуть текст, я не знаю точных требований).Дайте мне знать, если вам нужно больше разъяснений.

enter image description here

Я пытался включить комментарии в код, но дайте мне знать, если что-то нужно прояснить,Я хотел бы, чтобы форматирование кода было проще на SO ...

public class DiagonalLines
{
    private readonly Font font;
    private readonly Brush brush = new SolidBrush(Color.Black);
    private readonly Image image;
    private readonly float width;
    private readonly float height;

    private readonly float diagonalAngle;

    private readonly string savePath;

    public DiagonalLines(string path, string savePath)
    {
       this.image = Image.FromFile(path);

       width = image.Width;
            height = image.Height;

       //this could be optimized
       //you want to write perpendicular to the secondary diagonal, if I understood correctly
       //Math.Atan(height / width) => angle, in radians of the first diagonal
       //after applying "-" we obtain the angle, in radians, of the secondary diagonal
       //the rest of the first term is converting radians to degrees
       diagonalAngle = -(float)(Math.Atan(height / width) * 180 / Math.PI) + /* perpendicular*/ 90;

       this.font = new Font("Arial", (float)image.Width / 80); //write about 80 characters for a full horizontal text line
       this.savePath = savePath;
}

public void DrawLines(params string[] lines)
{
   using (Graphics g = Graphics.FromImage(image))
   {
       //M should be the largest character in most "western" fonts
       var lineHeight = g.MeasureString("M", font).Height;
       var halfTheLines =  (float)lines.Length / 2; //about half the lines should be "above" the midpoint of the secondary diagonal
       var offsetY = -(halfTheLines * lineHeight); //we scale the position against the line height
                                                   //same effect could probably be achieved with ScaleTransform

       g.DrawLine(Pens.Red, 0, height, width, 0); //draw the secondary diagonal

       foreach (var val in lines)
       {
            var size = g.MeasureString(val, font);

            g.ResetTransform();

            g.TranslateTransform(width / 2, height / 2); //go to center of image
            g.RotateTransform(diagonalAngle);

            //translate, to center the text and apply our offset
            g.TranslateTransform(-size.Width / 2, -size.Height / 2 + offsetY); 

            g.DrawString(val, font, brush, 0, 0);

            offsetY += lineHeight;
         }
     }

     image.Save(savePath);
}
}

static void Main(string[] args)
{
   var lines = new DiagonalLines("c:\\temp\\img\\poza.png", "c:\\temp\\img\\watermarked.jpg");
   lines.DrawLines("this", "that", "the other", "and another");
   Process.Start("c:\\temp\\img\\watermarked.jpg");
}
0 голосов
/ 08 февраля 2019

Я бы написал так больше.Там много маленьких изменений ... присмотрись!

        using (Graphics gr = Graphics.FromImage(selected_img))
        {
            int y = -50;
            int opacity = 127; // 0 to 255
            string txt = "watermark";
            int x = selected_img.Width;
            GraphicsState state = gr.Save();
            gr.ResetTransform();
            gr.TranslateTransform(selected_img.Width / 2, selected_img.Height / 2);
            gr.RotateTransform(45);
            gr.SmoothingMode = SmoothingMode.HighQuality;
            gr.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            using (Font font = new Font("Arial", 14.0f))
            {
                SizeF textSize = gr.MeasureString(txt, font);
                using (Brush brush = new SolidBrush(Color.FromArgb(opacity, Color.DarkGray)))
                {
                    for (int b = 1; b <= 5; b++, y += 25)
                    {
                        gr.DrawString(txt, font, brush, new PointF(-(textSize.Width / 2), y));
                    }
                }
            }
            gr.Restore(state);
        }
0 голосов
/ 08 февраля 2019

Вам нужно сначала перевести его, чтобы переместить начало координат:

Что-то вроде:

 gr.TranslateTransform(x, y);
 gr.RotateTransform(45);
 gr.TranslateTransform(-x, -y);

Вы можете измерить длину строки сначала, чтобы определить центр текста.

PSEUDO ..

 var size = gr.MeasureString(txt, font);

 var halfWidth = size.X / 2;
 var halfHeight = size.X / 2;

 gr.TranslateTransform(halfWidth , halfHeight);
 gr.RotateTransform(45);
 gr.TranslateTransform(-halfWidth , -halfHeight);

Не тестировалось ...

...