WPF實現圖片合成或加水印的方法【2種方法】。本站提示廣大學習愛好者:(WPF實現圖片合成或加水印的方法【2種方法】)文章只能為提供參考,不一定能成為您想要的結果。以下是WPF實現圖片合成或加水印的方法【2種方法】正文
本文實例講述了WPF實現圖片合成或加水印的方法。分享給大家供大家參考,具體如下:
最近項目中應用多次應用了圖片合成,為了今後方便特此記下。
在WPF下有兩種圖片合成的方式,一種還是用原來C#提供的GDI+方式,命名空間是System.Drawing 和 System.Drawing.Imaging,另一種是WPF中新添加的API,命名空間是 System.Windows.Media 和 System.Windows.Media.Imaging 。
我們來做一個簡單的例子,分別用上面的兩種方式實現,功能是在一個背景圖上面,畫一個頭像,然後在寫一個簽名。
首先准備一張背景圖(bg.jpg" />
把准備的素材拷貝到項目中,其文件屬性【復制到輸出目錄】選擇【始終復制】,【生成操作】選擇【內容】。
這裡貼一下兩種方式的主要代碼,具體代碼可以在文章最後點擊下載。
第一種方式
使用RenderTargetBitmap 和 DrawingVisual 方式
private BitmapSource MakePicture(string bgImagePath, string headerImagePath, string signature) { //獲取背景圖 BitmapSource bgImage = new BitmapImage(new Uri(bgImagePath, UriKind.Relative)); //獲取頭像 BitmapSource headerImage = new BitmapImage(new Uri(headerImagePath, UriKind.Relative)); //創建一個RenderTargetBitmap 對象,將WPF中的Visual對象輸出 RenderTargetBitmap composeImage = new RenderTargetBitmap(bgImage.PixelWidth, bgImage.PixelHeight, bgImage.DpiX, bgImage.DpiY, PixelFormats.Default); FormattedText signatureTxt = new FormattedText(signature, System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(System.Windows.SystemFonts.MessageFontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), 50, System.Windows.Media.Brushes.White); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); drawingContext.DrawImage(bgImage, new Rect(0, 0, bgImage.Width, bgImage.Height)); //計算頭像的位置 double x = (bgImage.Width / 2 - headerImage.Width) / 2; double y = (bgImage.Height - headerImage.Height) / 2 - 100; drawingContext.DrawImage(headerImage, new Rect(x, y, headerImage.Width, headerImage.Height)); //計算簽名的位置 double x2 = (bgImage.Width/2 - signatureTxt.Width) / 2; double y2 = y + headerImage.Height + 20; drawingContext.DrawText(signatureTxt, new System.Windows.Point(x2, y2)); drawingContext.Close(); composeImage.Render(drawingVisual); //定義一個JPG編碼器 JpegBitmapEncoder bitmapEncoder = new JpegBitmapEncoder(); //加入第一幀 bitmapEncoder.Frames.Add(BitmapFrame.Create(composeImage)); //保存至文件(不會修改源文件,將修改後的圖片保存至程序目錄下) string savePath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"\合成.jpg"; bitmapEncoder.Save(File.OpenWrite(Path.GetFileName(savePath))); return composeImage; }
第二種方式
利用原來的GDI+方式
private BitmapSource MakePictureGDI(string bgImagePath, string headerImagePath, string signature) { GDI.Image bgImage = GDI.Bitmap.FromFile(bgImagePath); GDI.Image headerImage = GDI.Bitmap.FromFile(headerImagePath); //新建一個畫板,畫板的大小和底圖一致 System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(bgImage.Width, bgImage.Height); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap); //設置高質量插值法 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //設置高質量,低速度呈現平滑程度 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //清空畫布並以透明背景色填充 g.Clear(System.Drawing.Color.Transparent); //先在畫板上面畫底圖 g.DrawImage(bgImage, new GDI.Rectangle(0, 0, bitmap.Width, bitmap.Height)); //再在畫板上畫頭像 int x = (bgImage.Width / 2 - headerImage.Width) / 2; int y = (bgImage.Height - headerImage.Height) / 2 - 100; g.DrawImage(headerImage, new GDI.Rectangle(x, y, headerImage.Width, headerImage.Height), new GDI.Rectangle(0, 0, headerImage.Width, headerImage.Height), GDI.GraphicsUnit.Pixel); //在畫板上寫文字 using (GDI.Font f = new GDI.Font("Arial", 20, GDI.FontStyle.Bold)) { using (GDI.Brush b = new GDI.SolidBrush(GDI.Color.White)) { float fontWidth = g.MeasureString(signature, f).Width; float x2 = (bgImage.Width / 2 - fontWidth) / 2; float y2 = y + headerImage.Height + 20; g.DrawString(signature, f, b, x2, y2); } } try { string savePath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"\GDI+合成.jpg"; bitmap.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg); return ToBitmapSource(bitmap); } catch (System.Exception e) { throw e; } finally { bgImage.Dispose(); headerImage.Dispose(); g.Dispose(); } } #region GDI+ Image 轉化成 BitmapSource [System.Runtime.InteropServices.DllImport("gdi32")] static extern int DeleteObject(IntPtr o); public BitmapSource ToBitmapSource(GDI.Bitmap bitmap) { IntPtr ip = bitmap.GetHbitmap(); BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( ip, IntPtr.Zero, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); DeleteObject(ip);//釋放對象 return bitmapSource; } #endregion
附:完整實例代碼點擊此處本站下載。
更多關於C#相關內容感興趣的讀者可查看本站專題:《C#常見控件用法教程》、《WinForm控件用法總結》、《C#數據結構與算法教程》、《C#面向對象程序設計入門教程》及《C#程序設計之線程使用技巧總結》
希望本文所述對大家C#程序設計有所幫助。
[db:作者簡介][db:原文翻譯及解析]