【问题标题】:Drawing Text on Image library在图像库上绘制文本
【发布时间】:2019-12-12 06:24:32
【问题描述】:

是否有任何开源库用于在 C# 中将文本绘制为图像?我整天都在为TextRenderergraphics.DrawString() 苦苦挣扎,但我从来没有接近获得像样的结果,我尝试了平滑、插值、TextRenderHint 的每一种组合,但质量总是半体面的。

这里有一些图片,这是我最好的:

它需要是什么样子:

这看起来确实不错,但是对于某些字符串,某些字母的字符间距似乎是错误的,并且字符串会倾斜。

设置是:

objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
              objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
              objGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.GammaCorrected;
              objGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
              objGraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
              objGraphics.TextContrast = 0;

格式为Png,背景为透明,方法为TextRenderer.Drawtext()。似乎文本的粗细是错误的,我认为平滑有问题,当我尝试加粗文本时,它几乎保持不变,但只有~10px的字体大小。

【问题讨论】:

  • 您在使用 Winforms 吗?您的目标是哪个版本的 .NET?
  • 我实际上在使用 ASP.NET 4.0
  • 我已将 ASP.NET 标记添加到您的帖子中。将来这样做会让您的问题在 ASP.NET 方面具有专业知识的人更容易看到
  • 向我们展示您的尝试。您可以使用 Graphics.DrawString、字体、画笔等在图像上绘制出色的文本。
  • @ose 谢谢。我忘记标记了。​​

标签: c# asp.net


【解决方案1】:

这是我用来为上传到我网站的照片添加版权水印的方法:

    //Add Watermark to photo.
    private System.Drawing.Image CreateWatermark(System.Drawing.Image imgPhoto, string Copyright)
    {
        Graphics g = Graphics.FromImage(imgPhoto);

        g.SmoothingMode = SmoothingMode.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;

        foreach (PropertyItem pItem in imgPhoto.PropertyItems)
        {
            imgPhoto.SetPropertyItem(pItem);
        }

        int phWidth = imgPhoto.Width;
        int phHeight = imgPhoto.Height;

        //create a Bitmap the Size of the original photograph
        Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

        bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

        //load the Bitmap into a Graphics object 
        Graphics grPhoto = Graphics.FromImage(bmPhoto);

        //------------------------------------------------------------
        //Step #1 - Insert Copyright message
        //------------------------------------------------------------

        //Set the rendering quality for this Graphics object
        grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

        //Draws the photo Image object at original size to the graphics object.
        grPhoto.DrawImage(
            imgPhoto,                               // Photo Image object
            new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
            0,                                      // x-coordinate of the portion of the source image to draw. 
            0,                                      // y-coordinate of the portion of the source image to draw. 
            phWidth,                                // Width of the portion of the source image to draw. 
            phHeight,                               // Height of the portion of the source image to draw. 
            GraphicsUnit.Pixel);                    // Units of measure 

        //-------------------------------------------------------
        //to maximize the size of the Copyright message we will 
        //test multiple Font sizes to determine the largest posible 
        //font we can use for the width of the Photograph
        //define an array of point sizes you would like to consider as possiblities
        //-------------------------------------------------------
        int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };

        Font crFont = null;
        SizeF crSize = new SizeF();

        //Loop through the defined sizes checking the length of the Copyright string
        //If its length in pixles is less then the image width choose this Font size.
        for (int i = 0; i < 7; i++)
        {
            //set a Font object to Arial (i)pt, Bold
            crFont = new Font("arial", sizes[i], FontStyle.Bold);
            //Measure the Copyright string in this Font
            crSize = grPhoto.MeasureString(Copyright, crFont);

            if ((ushort)crSize.Width < (ushort)phWidth)
                break;
        }

        //Since all photographs will have varying heights, determine a 
        //position 5% from the bottom of the image
        int yPixlesFromBottom = (int)(phHeight * .05);

        //Now that we have a point size use the Copyrights string height 
        //to determine a y-coordinate to draw the string of the photograph
        float yPosFromBottom = ((phHeight - yPixlesFromBottom) - (crSize.Height / 2));

        //Determine its x-coordinate by calculating the center of the width of the image
        float xCenterOfImg = (phWidth / 2);

        //Define the text layout by setting the text alignment to centered
        StringFormat StrFormat = new StringFormat();
        StrFormat.Alignment = StringAlignment.Near;

        //define a Brush which is semi trasparent black (Alpha set to 153)
        SolidBrush semiTransBrush2 = new SolidBrush(System.Drawing.Color.FromArgb(153, 0, 0, 0));

        //Draw the Copyright string
        grPhoto.DrawString(Copyright,                 //string of text
            crFont,                                   //font
            semiTransBrush2,                           //Brush
            new PointF(xCenterOfImg + 1, yPosFromBottom + 1),  //Position
            StrFormat);

        //define a Brush which is semi trasparent white (Alpha set to 153)
        SolidBrush semiTransBrush = new SolidBrush(System.Drawing.Color.FromArgb(153, 255, 255, 255));

        //Draw the Copyright string a second time to create a shadow effect
        //Make sure to move this text 1 pixel to the right and down 1 pixel
        grPhoto.DrawString(Copyright,                 //string of text
            crFont,                                   //font
            semiTransBrush,                           //Brush
            new PointF(xCenterOfImg, yPosFromBottom),  //Position
            StrFormat);                               //Text alignment
        imgPhoto = bmPhoto;
        return imgPhoto;
    }

【讨论】:

  • 感谢第一眼,它看起来真的很不错!无论如何,我找到了解决方案。我的问题是我在透明背景上绘制文本,而用任何背景颜色填充它时解决了它。但是查看这段代码可能会解决我可能遇到的更多问题。
【解决方案2】:

Using System.Drawing classes in ASP.NET is not supported.

具体来说,如果你使用它,在多线程负载下,你会遇到这样的异常:

Win32Exception: The operation completed successfully
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y,     Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
at System.Windows.Media.MediaContextNotificationWindow..ctor(MediaContext ownerMediaContext)
at System.Windows.Media.MediaContext..ctor(Dispatcher dispatcher)

也就是说,我们发现将所有绘图操作编组到单个 STA 线程似乎可以避免这些问题。

更新:已经五年了,我们仍然对这种方法没有任何问题。

【讨论】:

    猜你喜欢
    • 2017-07-07
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2011-12-03
    • 2016-11-04
    相关资源
    最近更新 更多