阅读提示:
《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。
《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。
尽可能保持二者内容一致,可相互对照。
本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程》中的ImageData.pas单元和《Delphi图像处理 -- 平面几何变换类》TransformMatrix.pas单元。
利用模版矩阵进行卷积操作,可以实现图片的彩色浮雕效果,下面的代码使用《Delphi图像处理 -- 图像卷积》中介绍的通用卷积过程,来实现图片的彩色浮雕效果:
var Data: TImageData; begin Data := GetImageData(TGpBitmap.Create('d:/56-3.jpg'), True); ImageConvolutionI(Data, [1, 1, 0, 0, 0, 0, 1, 0, -2]); DrawImage(Canvas, 0, 0, Data); FreeImageData(Data); end;
但是,同一般灰色浮雕的实现一样,没法实现任意角度的浮雕,为此,采用《Delphi图像处理 -- 灰度浮雕》同样的方法,可灵活的完成任意角度和大小的图片彩色浮雕效果,下面是整个代码:
procedure ImageColorSculpture(var Data: TImageData; Angle: Single; Size: LongWord); var x, y, Radius: Integer; xDelta, yDelta: Integer; xDelta2, yDelta2: Integer; width, height: Integer; dstOffset: Integer; src: TImageData; begin Radius := (Size + 1) shr 1; // 图像边框扩展半径 Angle := PI * Angle / 180; Size := Size shl 11; // Size = Size * 2048 xDelta := Round(Cos(Angle) * Size); yDelta := Round(Sin(Angle) * Size); xDelta2 := xDelta shl 1; yDelta2 := yDelta shl 1; x := (Radius shl 12) - xDelta; y := (Radius shl 12) - yDelta; width := x + (Data.Width shl 12); height := y + (Data.Height shl 12); if Data.AlphaFlag then ArgbConvertPArgb(Data); src := _GetExpandData(Data, Radius); asm push esi push edi push ebx mov eax, Data lea edx, src call _SetCopyRegs mov dstOffset, ebx pxor mm7, mm7 // mm7 = 00 00 00 00 00 00 00 00 pxor xmm7, xmm7 mov esi, src.Scan0 mov ebx, src.Stride mov ecx, y // for (; y < Height; y += 1096) @@yLoop: // { mov edx, x // for (; x < Width; x += 4096 @@xLoop: // { push edx push ecx // x1 = x, y1 = y call GetSrcColor // mm0 = 00 A1 00 R1 00 G1 00 B1 movq mm1, mm0 // mm1 = mm0(ARGB1) add edx, xDelta // x2 = x, y2 = y - yDelta call GetSrcColor // mm0 = 00 A2 00 R2 00 G2 00 B2 paddw mm1, mm0 // mm1 += mm0(ARGB2) add ecx, yDelta2 sub edx, xDelta // x3 = x - xDelta, y3 = y + yDelta call GetSrcColor // mm0 = 00 A3 00 R3 00 G3 00 B3 paddw mm1, mm0 // mm1 += mm0(ARGB3) add edx, xDelta2 // x0 = x + xDelta, y0 = y + yDelta call GetSrcColor // mm0 = 00 A0 00 R0 00 G0 00 B0 psllw mm0, 1 // mm0 = A0*2 R0*2 G0*2 B0*2 psubsw mm1, mm0 // mm6 = (ARGB1+ARGB2+ARGB3) - ARGB0*2 packuswb mm1, mm7 // mm6 = 00 00 00 00 A R G B mov al, [edi].TARGBQuad.Alpha movd [edi], mm1 // *edi = mm0 mov [edi].TARGBQuad.Alpha, al pop ecx pop edx add edi, 4 // edi += 4 add edx, 1000h cmp edx, width jl @@xLoop // } add ecx, 1000h add edi, dstOffset cmp ecx, height jl @@yLoop // } emms pop ebx pop edi pop esi end; FreeImageData(src); if Data.AlphaFlag then PArgbConvertArgb(Data); end;
下面是一个简单的测试代码:
procedure TForm1.Button3Click(Sender: TObject); var bmp: TGpBitmap; g: TGpGraphics; data: TImageData; begin bmp := TGpBitmap.Create('..\media\20041001.jpg'); g := TGpGraphics.Create(Canvas.Handle); g.DrawImage(bmp, 0, 0); data := LockGpBitmap(bmp); ImageColorSculpture(data, 45, 3); UnlockGpBitmap(bmp, data); g.DrawImage(bmp, 0, data.Height); g.Free; bmp.Free; end;
原始图:
彩色浮雕效果图:
《Delphi图像处理》系列使用GDI+单元下载地址和说明见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。
因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:[email protected]
这里可访问《Delphi图像处理 -- 文章索引》。