位图图形:在磁盘上保存时没有绘制字符串 - 在内存流时工作

时间:2013-08-07 10:44:56

标签: c# asp.net-mvc bitmap drawstring

我使用Bitmap使用Drawing.Graphics对象创建PNG图片。我创建了一个位图,插入一个背景图像并绘制一些字符串。

现在,当我将图像保存在磁盘上时,文件没有我的字符串!

我在ASP.NET MVC中这样做,这是我的控制器签名:

    [AcceptVerbs(HttpVerbs.Get)]
    public string GetNewsletterPicture(string headline, string tagline)

当我不将图像保存在磁盘上而是从FileStreamResult返回MemoryStream时,图像看起来很完美。

所以有一些问题,当我将图像保存到磁盘时,字符串被“遗忘”了。

有什么想法吗?

我的代码

ColorConverter converter = new ColorConverter();
        Color textColor = (Color)converter.ConvertFromString("#FF58595B");
        int width = 598;
        int height = 77;
        int offSet = 40;
        int shadowOffset = 1;

        var bmp = new Bitmap(width, height);
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.Clear(Color.LightGray);
            Image backgroundImg = new Bitmap(Server.MapPath("~/Static/Images/bgimg.png"));
            g.DrawImage(backgroundImg,0,0);

            StringFormat sf= new StringFormat();
            sf.Alignment = StringAlignment.Center;

            var rectangleTop = new RectangleF(0, 0, width, height);
            var rectangleTopShadowHack = new RectangleF(shadowOffset, shadowOffset, width + shadowOffset, height + shadowOffset);
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

            // only show headline and center it
            if (!string.IsNullOrEmpty(tagline))
            {
                var rectangleBottomShadowHack = new RectangleF(shadowOffset, offSet + shadowOffset, width + shadowOffset, height - offSet + shadowOffset);
                var rectangleBottom = new RectangleF(0, offSet, width, height - offSet);

                g.DrawString(tagline, new Font("Verdana", 18), new SolidBrush(Color.White), rectangleBottomShadowHack, sf);
                g.DrawString(tagline, new Font("Verdana", 18), new SolidBrush(textColor), rectangleBottom, sf);
            }
            else
            {
                sf.LineAlignment = StringAlignment.Center;
            }
            g.DrawString(headline, GetFont("Sentinel-Bold", 28, FontStyle.Bold), new SolidBrush(Color.White), rectangleTopShadowHack, sf);
            g.DrawString(headline, GetFont("Sentinel-Bold", 28, FontStyle.Bold), new SolidBrush(textColor), rectangleTop, sf);

            g.Save();

            var fileName = Guid.NewGuid().ToString() + ".png";
            var path = Server.MapPath("~/Static/Previews/" + fileName);
            bmp.Save(path, ImageFormat.Png);

            return fileName;

如果有疑问,那就是没有保存在图片上的g.DrawString。

NEW atttempt(仍然无效):

[AcceptVerbs(HttpVerbs.Get)]
        public string GetNewsletterPicture(string headline, string tagline)
        {
            ColorConverter converter = new ColorConverter();
            Color textColor = (Color)converter.ConvertFromString("#FF58595B");
            int width = 598;
            int height = 77;
            int offSet = 40;
            int shadowOffset = 1;

            var bmp = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.LightGray);
                Image backgroundImg = new Bitmap(Server.MapPath("~/Static/Images/bgimg.png"));
                g.DrawImage(backgroundImg,0,0);

                StringFormat sf= new StringFormat();
                sf.Alignment = StringAlignment.Center;

                var rectangleTop = new RectangleF(0, 0, width, height);
                var rectangleTopShadowHack = new RectangleF(shadowOffset, shadowOffset, width + shadowOffset, height + shadowOffset);
                g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

                // only show headline and center it
                if (!string.IsNullOrEmpty(tagline))
                {
                    var rectangleBottomShadowHack = new RectangleF(shadowOffset, offSet + shadowOffset, width + shadowOffset, height - offSet + shadowOffset);
                    var rectangleBottom = new RectangleF(0, offSet, width, height - offSet);

                    g.DrawString(tagline, new Font("Verdana", 18), new SolidBrush(Color.White), rectangleBottomShadowHack, sf);
                    g.DrawString(tagline, new Font("Verdana", 18), new SolidBrush(textColor), rectangleBottom, sf);
                }
                else
                {
                    sf.LineAlignment = StringAlignment.Center;
                }
                g.DrawString(headline, GetFont("Sentinel-Bold", 28, FontStyle.Bold), new SolidBrush(Color.White), rectangleTopShadowHack, sf);
                g.DrawString(headline, GetFont("Sentinel-Bold", 28, FontStyle.Bold), new SolidBrush(textColor), rectangleTop, sf);

                g.Flush(FlushIntention.Sync);
            }

            var fileName = Guid.NewGuid().ToString() + ".png";
            var path = Server.MapPath("~/Static/Previews/" + fileName);
            bmp.Save(path, ImageFormat.Png);

            return fileName;


            //MemoryStream stm = new MemoryStream();
            //bmp.Save(stm,System.Drawing.Imaging.ImageFormat.Png);
            //stm.Position = 0;

            //return new FileStreamResult(stm, "image/png");
        }

1 个答案:

答案 0 :(得分:1)

我无法确定,但看起来您可能会g.Save()g.Flush()混淆。

您需要拨打g.Flush(FlushIntention.Sync)而不是g.Save()。你应该也可以调用using块的的bmp.Save()

var bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp))
{
  //...
  g.Flush(FlushIntention.Sync);
}

var fileName = Guid.NewGuid().ToString() + ".png";
var path = Server.MapPath("~/Static/Previews/" + fileName);

bmp.Save(path, ImageFormat.Png)

Save()用于保存当前图形状态,以便您可以对其进行修改,然后在以后恢复它。:

GraphicsState oldState = g.Save();

// Make some changes to the graphics state...

g.Restore(oldState);
另一方面,

Flush()用于强制图形对象完成任何挂起的操作。通过传递FlushIntention.Sync作为参数,Flush()将不会返回,直到刷新完成。