WPF 实现图片水印的两种方式

//使用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));
    Random rnd = new Random();
    //计算签名的位置
    double x2 = (bgImage.Width / 2 - signatureTxt.Width) / 2 + rnd.Next(200);
    double y2 = y + headerImage.Height + 20 + rnd.Next(100);
    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)));//该方法会导致图片文件被锁
    using (FileStream fs = new FileStream(savePath, FileMode.OpenOrCreate))
    {
        bitmapEncoder.Save(fs);
    }
    bitmapEncoder = null;
       
    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


知识共享许可协议
《WPF 实现图片水印的两种方式》常伟华 创作。
采用 知识共享 署名-相同方式共享 3.0 中国大陆 许可协议进行许可。
相邻依据:发表时间
  • 多说评论
  • 签名
  • 新浪微博
  • 默认评论
  • Tab Header 5

0 条评论 / 点击此处发表评论

Tab Content 5

Warning: file_get_contents(http://ip.taobao.com/service/getIpInfo.php?ip=3.237.200.21) [function.file-get-contents]: failed to open stream: ӷһʱûȷ𸴻ӵûзӦӳʧܡ in D:\wwwroot\changweihua\wwwroot\v\content\templates\darklight\vrecord.php on line 129

开发技术


开发平台和工具

sitemap     21061.42ms