天天看點

用.net在畫出镂空圖檔

最近的一個項目需要用到這個東西,冥思苦想了好幾天。還是在同僚的幫助下,完成此項難題,希望能夠幫助以後的博友們 !

廢話不多說,先看看效果圖吧。

用.net在畫出镂空圖檔

 首先寫一下講一下思路,首先畫一張圖,當你的背景,然後在圖上寫字,寫的字型最好是粗體,不好太多字,顔色最後用一般不常用的顔色,然後讀取這些顔色所在的位置,

設定成透明的,即可。

#region 文字生成镂空圖檔 


        static string BuildTextImage(string text, string bgImage)
        {
            int ImgWidth = 0, ImgHeight = 0, StartSize = 30;

            #region 複制背景圖特殊顔色填寫文字--
            
            var bucket = OpenUtility.GetBucket(bgImage);
            var result = FileHub.GetStream(bucket, bgImage);
            if (result.Status != UFile.Data.ActionStatus.SUCCESS)
            {
                return "";
            }

            var stream = result.Data;

            Bitmap bitmap = new Bitmap(stream);

            ImgWidth = bitmap.Width;
            ImgHeight = bitmap.Height;

            Graphics g = Graphics.FromImage(bitmap);
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            g.FillRectangle(new SolidBrush(Color.White), 0, 0, bitmap.Width, bitmap.Height);
            using (Font font1 = new Font("Arial", 1200, FontStyle.Bold, GraphicsUnit.Pixel))
            {
                Rectangle rect1 = new Rectangle(0, 100, ImgWidth, ImgHeight);
                StringFormat stringFormat = new StringFormat();
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

                Font goodFont = FindGoodFont(g, text, rect1.Size, font1, GraphicsUnit.Pixel);
                g.DrawString(text, goodFont, Brushes.Black, rect1, stringFormat);
            }
            g.Dispose();
            //bitmap.Save(text + ".jpg", ImageFormat.Jpeg);

            #endregion

            #region 畫格子

            Bitmap reff = new Bitmap(ImgWidth, ImgHeight);
            Graphics gi = Graphics.FromImage(reff);

            Image img = Image.FromStream(stream);
            gi.DrawImage(img, new Rectangle(0, 0, ImgWidth, ImgHeight));

            var rows = ImgHeight / StartSize;
            var cols = ImgWidth / StartSize;
            var coords = new List<string>();
            for (int j = 0; j < rows; j++)
            {
                for (int i = 0; i < cols; i++)
                {
                    var total = StartSize * StartSize;
                    var cur = 0;
                    for (int ii = 0; ii < StartSize; ii++)
                    {
                        for (int jj = 0; jj < StartSize; jj++)
                        {
                            var posx = i * StartSize + ii;
                            var posy = j * StartSize + jj;
                            byte color = bitmap.GetPixel(posx, posy).R;
                            if (color == 0)
                            {
                                cur++;
                                reff.SetPixel(posx, posy, Color.Transparent);
                            }
                        }
                    }
                    if (cur > total * 0.02)
                    {
                        coords.Add("[" + i + "," + j + "]");
                    }
                }
            }

            //StreamWriter sw = new StreamWriter(text + ".txt");
            //sw.Write("[" + string.Join(",", coords.ToArray()) + "]");
            //sw.Close();

            gi.Dispose();

            string path = string.Empty;
            //reff.Save("d:\\"+Guid.NewGuid.ToString() + "_cover.png", ImageFormat.Png);
            using (var ms = new System.IO.MemoryStream())
            {
                reff.Save(ms, ImageFormat.Png);

                var mime = OpenUtility.GetMimeType(bgImage);

                path = "/Uploads/Files/" + string.Format("{0:yyyy/MM/dd}", DateTime.Now) + "/" + Guid.NewGuid().ToString() + ".png";
                FileHub.Put(bucket, path, ms, mime);
            }
            #endregion 

            return path;

        }

        private static Font FindGoodFont(Graphics Graf, string sStringToFit,
                                    Size TextRoomAvail,
                                    Font FontToUse,
                                    GraphicsUnit FontUnit)
        {
            // Find out what the current size of the string in this font is
            SizeF RealSize = Graf.MeasureString(sStringToFit, FontToUse);
            if ((RealSize.Width <= TextRoomAvail.Width) && (RealSize.Height <= TextRoomAvail.Height))
            {
                // The current font is fine...
                return FontToUse;
            }

            // Either width or height is too big...
            // Usually either the height ratio or the width ratio
            // will be less than 1. Work them out...
            float HeightScaleRatio = TextRoomAvail.Height / RealSize.Height;
            float WidthScaleRatio = TextRoomAvail.Width / RealSize.Width;

            // We'll scale the font by the one which is furthest out of range...
            float ScaleRatio = (HeightScaleRatio < WidthScaleRatio) ? ScaleRatio = HeightScaleRatio : ScaleRatio = WidthScaleRatio;
            float ScaleFontSize = FontToUse.Size * ScaleRatio;

            // Retain whatever the style was in the old font...
            FontStyle OldFontStyle = FontToUse.Style;

            // Get rid of the old non working font...
            FontToUse.Dispose();

            // Tell the caller to use this newer smaller font.
            FontToUse = new Font(FontToUse.FontFamily,
                                    ScaleFontSize,
                                    OldFontStyle,
                                    FontUnit);
            return FontToUse;
        } #endregion      

繼續閱讀