注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

鑫淼梦园的博客

圆你的梦想 从这里开始

 
 
 

日志

 
 

GDI+ 在Delphi程序的应用 -- Photoshop浮雕效果(续)  

2013-06-24 15:44:39|  分类: delphi xe4 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

GDI+ 在Delphi程序的应用 -- Photoshop浮雕效果(续)

  1. // Photoshop浮雕。参数:Data: 图像数据, Angle: 角度, Size: 长度, Num: 数量
  2. procedure PSSculpture(Data: TImageData; Angle: Single;
  3.    Size: LongWord; Num: LongWord = 100);
  4. var
  5.    x, y: Integer;
  6.    Width, Height: Integer;
  7.    xDelta, yDelta: Integer;
  8.    P: PRGBQuad;
  9.    P0, P1: TRGBQuad;
  10.    Buf: Pointer;
  11.    Src: TImageData;
  12. begin
  13.   if Size = 0 then
  14.     raise Exception.Create('Sculpture can not be size 0');
  15.    Angle := PI * Angle / 180;
  16.    Size := Size shl 16;
  17.   if Num > 500 then Num := 500;
  18.    xDelta := Round((Cos(Angle) * Size) / 2);
  19.    yDelta := Round((Sin(Angle) * Size) / 2);
  20.    Width := Data.Width shl 16;
  21.    Height := Data.Height shl 16;
  22.    GetMem(Buf, Data.Height * Data.Stride);
  23.   try
  24.      Move(Data.Scan0^, Buf^, Data.Height * Data.Stride);
  25.      Move(Data, Src, Sizeof(TImageData));
  26.      Src.Scan0 := Buf;
  27.      P := Data.Scan0;
  28.      y := 0;
  29.     while y < Height do
  30.     begin
  31.        x := 0;
  32.       while x < Width do
  33.       begin
  34.          P0 := TRGBQuad(GetBilinearColor(x - xDelta, y - yDelta, Src));
  35.          P1 := TRGBQuad(GetBilinearColor(x + xDelta, y + yDelta, Src));
  36.          P^.rgbBlue := Max(0, Min(255, Num * (P0.rgbBlue - P1.rgbBlue) div 100 + 128));
  37.          P^.rgbGreen := Max(0, Min(255, Num * (P0.rgbGreen - P1.rgbGreen) div 100 + 128));
  38.          P^.rgbRed := Max(0, Min(255, Num * (P0.rgbRed - P1.rgbRed) div 100 + 128));
  39.          Inc(P);
  40.          Inc(x, $10000);
  41.       end;
  42.        Inc(y, $10000);
  43.     end;
  44.   finally
  45.      FreeMem(Buf);
  46.   end;
  47. end;
  48. // Photoshop浮雕。参数:Bmp: GDI+图像, Angle: 角度, Size: 长度, Num: 数量
  49. procedure GdipPSSculpture(Bmp: TGpBitmap; Angle: Single;
  50.    Size: LongWord; Num: LongWord = 100);
  51. var
  52.    Data: TBitmapData;
  53. begin
  54.    Data := Bmp.LockBits(GpRect(0, 0, Bmp.Width, Bmp.Height), [imRead, imWrite], pf32bppARGB);
  55.   try
  56.      PSSculpture(TImageData(Data), Angle, Size, Num);
  57.   finally
  58.      Bmp.UnlockBits(Data);
  59.   end;
  60. end;
  61. // Photoshop浮雕。参数:Bmp: Bitmap图像, Angle: 角度, Size: 长度, Num: 数量
  62. procedure BitmapPSSculpture(Bmp: TBitmap; Angle: Single;
  63.    Size: LongWord; Num: LongWord = 100);
  64. begin
  65.    PSSculpture(GetImageData(Bmp), 360 - Angle, Size, Num);
  66. end;

    以上代码即可用GDI+实现图像浮雕效果,也可直接用Delphi的TBitmap实现图像浮雕效果,因为TBitmap图像地址GDI+的图像地址排列不一样,为了保证2者处理的效果完全一样,所以用360 - 原角度参数。本代码中浮雕角度参数与Phoposhop是不相同的,Photoshop是以右边为0度,逆时钟调整角度,而本代码是以左边为0度,顺时钟方向调整角度。

    在上述代码中,并没有将原始图像进行实际的缩放,而是直接在原始图像数据地址上,通过二次线性插值法找到并计算出2个逻辑点的颜色值而形成差值的。其中的GetBilinearColor过程是以前就写好的定点数二次线性插值缩放过程中部分代码,浮雕效果实现过程中,没有用到其中的Alpha,所以,有关Alpha处理的语句完全可以去掉。

    下面是一个用GDI+实现图像浮雕效果的测试程序代码:

  1. unit Main;
  2. interface
  3. uses
  4.    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5.    Dialogs, StdCtrls, ExtCtrls, Gdiplus;
  6. type
  7.    TForm1 = class(TForm)
  8.      PaintBox1: TPaintBox;
  9.      Label1: TLabel;
  10.      Edit1: TEdit;
  11.      Label2: TLabel;
  12.      Edit2: TEdit;
  13.      Label3: TLabel;
  14.      Edit3: TEdit;
  15.      Button1: TButton;
  16.      Button2: TButton;
  17.     procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  18.     procedure FormCreate(Sender: TObject);
  19.     procedure FormDestroy(Sender: TObject);
  20.     procedure Button1Click(Sender: TObject);
  21.     procedure Button2Click(Sender: TObject);
  22.     procedure PaintBox1Paint(Sender: TObject);
  23.   private
  24.     { Private declarations }
  25.      FBmp: TGpBitmap;
  26.      FSource: TGpBitmap;
  27.   public
  28.     { Public declarations }
  29.   end;
  30. var
  31.    Form1: TForm1;
  32. implementation
  33. uses Math, BitmapUtils, GpBmpUtils;
  34. {$R *.dfm}
  35. procedure TForm1.Button1Click(Sender: TObject);
  36. var
  37.    Angle: Single;
  38.    Size: LongWord;
  39.    Num: LongWord;
  40. begin
  41.   if Assigned(FBmp) then
  42.      FBmp.Free;
  43.    FBmp := FSource.Clone(GpRect(0, 0, FSource.Width, FSource.Height), pf32bppARGB);
  44.    Angle := StrToFloat(Edit1.Text);
  45.    Size := StrToInt(Edit2.Text);
  46.    Num := StrToInt(Edit3.Text);
  47.    GdipPSSculpture(FBmp, Angle, Size, Num);
  48.    PaintBox1.Invalidate;
  49. end;
  50. procedure TForm1.Button2Click(Sender: TObject);
  51. begin
  52.    Close;
  53. end;
  54. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
  55. begin
  56.   if (Key >= #32) and not (Key in ['0'..'9']) then
  57.      Key := #0;
  58. end;
  59. procedure TForm1.FormCreate(Sender: TObject);
  60. begin
  61.    FSource := TGpBitmap.Create('D:\VclLib\GdiplusDemo\Media\20041001.jpg');
  62.    DoubleBuffered := True;
  63.    Button1.Click;
  64. end;
  65. procedure TForm1.FormDestroy(Sender: TObject);
  66. begin
  67.    FSource.Free;
  68.    FBmp.Free;
  69. end;
  70. procedure TForm1.PaintBox1Paint(Sender: TObject);
  71. var
  72.    g: TGpGraphics;
  73. begin
  74.    g := TGpGraphics.Create(PaintBox1.Canvas.Handle);
  75.   try
  76.      g.DrawImage(FSource, 0, 0);
  77.      g.TranslateTransform(0, FSource.Height);
  78.      g.DrawImage(FBmp, 0, 0);
  79.   finally
  80.      g.Free;
  81.   end;
  82. end;
  83. end.

    运行效果图:

GDI+ 在Delphi程序的应用 -- Photoshop浮雕效果(续) - 鑫淼梦园 - 鑫淼梦园的博客

    和Photoshop浮雕效果对比,基本一致,说明我对其算法实现了完全“破解”,虽然这个算法不是很难,但也费了我不少时间。

    代码中所用Gdiplus单元下载地址及BUG更正见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。建议和指导请来信:

  评论这张
 
阅读(385)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017