博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF 下两种图片合成或加水印的方式
阅读量:5818 次
发布时间:2019-06-18

本文共 5798 字,大约阅读时间需要 19 分钟。

最近项目中应用多次应用了图片合成,为了今后方便特此记下。

在WPF下有两种图片合成的方式,一种还是用原来C#提供的GDI+方式,命名空间是System.Drawing 和 System.Drawing.Imaging,另一种是WPF中新添加的API,命名空间是 System.Windows.Media 和 System.Windows.Media.Imaging 。

我们来做一个简单的例子,分别用上面的两种方式实现,功能是在一个背景图上面,画一个头像,然后在写一个签名。

首先准备一张背景图(bg.jpg)和两个头像图片(tiger.png 和 lion.png)最后的生成的图片效果如下图:

把准备的素材拷贝到项目中,其文件属性【复制到输出目录】选择【始终复制】,【生成操作】选择【内容】。

这里贴一下两种方式的主要代码,具体代码可以在文章最后点击下载。

第一种方式

使用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

转载于:https://www.cnblogs.com/lxblog/archive/2012/11/29/2794719.html

你可能感兴趣的文章
Oracle性能优化--DBMS_PROFILER
查看>>
uva-317-找规律
查看>>
Event事件的兼容性(转)
查看>>
我的2014-相对奢侈的生活
查看>>
zoj 2412 dfs 求连通分量的个数
查看>>
Java设计模式
查看>>
一文读懂 AOP | 你想要的最全面 AOP 方法探讨
查看>>
Spring Cloud 微服务分布式链路跟踪 Sleuth 与 Zipkin
查看>>
ORM数据库框架 SQLite 常用数据库框架比较 MD
查看>>
华为OJ 名字美丽度
查看>>
微信公众号与APP微信第三方登录账号打通
查看>>
onchange()事件的应用
查看>>
Windows 下最佳的 C++ 开发的 IDE 是什么?
查看>>
软件工程师成长为架构师必备的十项技能
查看>>
python 异常
查看>>
百度账号注销
查看>>
mysql-This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决
查看>>
BIEE Demo(RPD创建 + 分析 +仪表盘 )
查看>>
Cocos2dx 3.0开发环境的搭建--Eclipse建立在Android工程
查看>>
基本概念复习
查看>>