zoukankan      html  css  js  c++  java
  • Delphi GDI+实现水印功能

     利用GDI+可以很方便的制作带水印效果的图片,网上介绍这方面的文章也很多,但鲜有Delphi的,本文参照网上文章http://www.codeproject.com/KB/GDI-plus/watermark.aspx介绍的方法,用Delphi 2007制作水印效果图片,原代码如下:

    unit Main;
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Gdiplus, StdCtrls;
    
    type
      TMainForm = class(TForm)
        Button1: TButton;
        procedure FormPaint(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        Photo: TGpImage;
        PhWidth: Integer;
        PhHeight: Integer;
        Watermark: TGpImage;
        WmWidth: Integer;
        WmHeight: Integer;
        Bmp: TGpBitmap;
      public
        { Public declarations }
      end;
    
    var
      MainForm: TMainForm;
    
    implementation
    
    uses GdipTypes;
    
    {$R *.dfm}
    
    procedure TMainForm.Button1Click(Sender: TObject);
    var
      Clsid: TGUID;
      Parameters: TEncoderParameters;
      Quality: Integer;
    begin
      // 设置图像品质编码参数
      Parameters.Count := 1;
      Parameters.Parameter[0].Guid := EncoderQuality;
      Parameters.Parameter[0].ValueType := EncoderParameterValueTypeLong;
      Parameters.Parameter[0].NumberOfValues := 1;
      // 设置参数的值:品质等级,最高为100,图像文件大小与品质成正比
      Quality := 100;
      Parameters.Parameter[0].Value := @Quality;
    
      if GetEncoderClsid('image/jpeg', Clsid) then
        Bmp.Save('WatermarkPhoto.jpg', Clsid, @Parameters);
    end;
    
    procedure TMainForm.FormCreate(Sender: TObject);
    const
      ColorMatrix: TColorMatrix =
      (
        (1.0, 0.0, 0.0, 0.0, 0.0),
        (0.0, 1.0, 0.0, 0.0, 0.0),
        (0.0, 0.0, 1.0, 0.0, 0.0),
        (0.0, 0.0, 0.0, 0.3, 0.0),
        (0.0, 0.0, 0.0, 0.0, 1.0)
      );
      WorkingDirectory = '....Media';
      copyright = 'Copyright © 2008 - Maozefa';
    var
      gp: TGpGraphics;
      imageAttr: TGpImageAttributes;
      strFormat: TGpStringFormat;
      font: TGpFont;
      x, y: Single;
    begin
      // 读取原始图片
      Photo := TGpImage.Create(WorkingDirectory + '100_0349.jpg');
      PhWidth := Photo.Width;
      PhHeight := Photo.Height;
      // 读取水印图片
      Watermark := TGpImage.Create(WorkingDirectory + 'Watermark.bmp');
      WmWidth := Watermark.Width;
      WmHeight := Watermark.Height;
      // 建立一个新的位图,分辨率为72
      Bmp := TGpBitmap.Create(PhWidth, PhHeight, pf32bppArgb);
      Bmp.SetResolution(72, 72);
      // 建立新位图的画布,并设置图像显示质量和文本显示质量
      gp := TGpGraphics.Create(Bmp);
      gp.SmoothingMode := smAntiAlias;
      gp.TextRenderingHint := thAntiAlias;
      // 在画布上画原始图片
      gp.DrawImage(Photo, GpRect(0, 0, PhWidth, PhHeight),
                   0, 0, PhWidth, PhHeight, utPixel);
      // 建立图像显示辅助类
      imageAttr := TGpImageAttributes.Create;
      // 设置透明颜色为水印图片四角的底色,水印图显示为圆角图片
      imageAttr.SetColorKey($ff00ff00, $ff00ff00, ctBitmap);
      // 设置水印图片不透明度为0.3
      imageAttr.SetColorMatrix(ColorMatrix, cfDefault, ctBitmap);
      // 在画布左上角画水印图
      gp.DrawImage(Watermark, GpRect({PhWidth - WmWidth - }10, 10, WmWidth, WmHeight),
                   0, 0, WmWidth, WmHeight, utPixel, imageAttr);
      // 设置文本字体和显示格式
      font := TGpFont.Create('arial', 16, [fsBold]);
      strFormat := TGpStringFormat.Create;
      strFormat.Alignment := saCenter;
      // 在画布下方居中显示阴影文本
      x := PhWidth / 2;
      y := PhHeight - 26;
      gp.DrawString(copyright, font, Brushs[$99000000], x + 1, y + 1, strFormat);
      gp.DrawString(copyright, font, Brushs[$99ffffff], x, y, strFormat);
    
      font.Free;
      strFormat.Free;
      imageAttr.Free;
      gp.Free;
    end;
    
    procedure TMainForm.FormDestroy(Sender: TObject);
    begin
      Photo.Free;
      Watermark.Free;
      Bmp.Free;
    end;
    
    procedure TMainForm.FormPaint(Sender: TObject);
    var
      g: TGpGraphics;
    begin
      g := TGpGraphics.Create(Canvas.Handle);
      // 显示原始图片
      g.DrawImage(Photo, 0, 0, PhWidth, PhHeight);
      // 显示水印原始图片
      g.TranslateTransform(0, PhHeight + 5);
      g.DrawImage(Watermark, 0, 0, WmWidth, WmHeight);
      // 显示带水印和文本的图像
      g.TranslateTransform(PhWidth, -(PhHeight + 5));
      g.DrawImage(Bmp, 0, 0, PhWidth, PhHeight);
      g.Free;
    end;
    
    end.

    程序运行界面:

        代码中已经进行了注释,不再累叙,针对本文所参考的文章内容(Addr:http://www.codeproject.com/KB/GDI-plus/watermark.aspx),作几点说明:

        1、在参考的文章中,对文本字体、显示位置进行了测试和计算,本文为强调主要内容,对这些代码进行了简化;

        2、在水印底色透明处理中,原文采用的是TGpImageAttributes.SetRemapTable方法,而本文采用的则是TGpImageAttributes.SetColorKey方法,效果是一样的,具体原理可参照我的文章《GDI+ 在Delphi程序的应用 -- 图像的透明显示技巧》;

        3、因图片保存为jpeg格式文件时,GDI+自动对图像进行压缩,导致图片效果较差,所以本文保存图片时设置了图像品质编码参数;

        4、本文采用的GDI+单元介绍和下载地址见《GDI+ for VCL基础 -- GDI+ 与 VCL》。

        如有错误或者指教,请来信:maozefa@hotmail.com

    后记:有朋友用C++写本文代码,编译时出现LINK Error: unresolved external '_EncoderQuality' referenced ...错误,其原因是EncoderQuality是用DEFINE_GUID宏定义的GUID,而编译器误认为外部变量,所以出现链接错误。解决的办法是:在#include <gdiplus.h>前添加#include <initguid.h>

    好的代码像粥一样,都是用时间熬出来的
  • 相关阅读:
    BSOJ 4490 避难向导
    【水题】求条件最大值
    【模拟】神奇的树
    【模拟】2014ACM/ICPC亚洲区北京站-A-(Curious Matt)
    【模拟】refresh的停车场
    数据结构实验之栈三:后缀式求值 (stack)
    【STL】Message Flood(set)
    【STL】完美网络(优先队列实现)
    【搜索BFS】走迷宫(bfs)
    【STL】deque双向队列(转载)
  • 原文地址:https://www.cnblogs.com/jijm123/p/14193262.html
Copyright © 2011-2022 走看看