阅读提示:

    《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。

    《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。

    尽可能保持二者内容一致,可相互对照。

    本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程》中的ImageData.pas单元和《Delphi图像处理 -- 平面几何变换类》TransformMatrix.pas单元。

实现图像浮雕效果的一般原理是,将图像上每个像素点与其对角线的像素点形成差值,使相似颜色值淡化,不同颜色值突出,从而产生纵深感,达到浮雕的效果,具体的做法是用处于对角线的2个像素值相减,再加上一个背景常数,一般为128而成。这种算法的特点是简单快捷,缺点是不能调节图像浮雕效果的角度和深度。

用Photoshop实现的图像浮雕效果,可以任意调节浮雕角度和深度(2个像素点的距离),还可以调整浮雕像素差值的数量。其基本算法原理和一般浮雕效果相同,但是具体做法不一样:对每个要处理的像素点,首先按照浮雕角度和深度计算处2个相应点的位置,然后计算这2个位置的颜色值,并使之形成差值,再乘上浮雕差值数量百分比,最后加上128的背景色。注意,这里计算的2个相应点是逻辑点,而不是实际的像素点,比如实现一个45度角,深度为3的图像浮雕效果,对每个像素点P(x, y),其对应的2个逻辑点的位置分别是P0(x - 3 * 0.7071 / 2, y - 3 * 0.7071 / 2)和P1(x + 3 * 0.7071 / 2, y + 3 * 0.7071 / 2),显然,对于这样的2个逻辑点,是不能直接从图像中找到其对应的像素点的,如果简单地对其四舍五入处理,将会造成大量的,由不同角度和深度而形成的相同的浮雕效果,这可不是我们想要的结果,而且使浮雕角度和深度参数失去了它原本的意义。为此,必须对原始图像按浮雕角度和深度进行缩放后,再对每个像素点进行浮雕效果处理,完毕再缩放回原图的大小,从而完成整个浮雕效果过程。下面是我经过反复试验后,写的Photoshop浮雕效果实现过程代码:

procedure GetSrcColor;
asmpush      esi           // esi = src.Scan0mov       eax, ecxsar       eax, 12imul      eax, ebxadd       esi, eax      // esi += (y / 4096 * src.Stride)mov       eax, edxsar       eax, 12shl       eax, 2add       esi, eax      // esi +=  (x / 4096 * 4)call      _GetBilinearColormovd      eax, xmm0movd      mm0, eaxpunpcklbw mm0, mm7      // return mm0 = ARGB (word * 4)pop       esi
end;procedure ImageGraySculpture(var Data: TImageData;Angle: Single; Size: LongWord; Num: LongWord = 100);
varx, y, Radius: Integer;xDelta, yDelta: Integer;width, height: Integer;dstOffset: Integer;src: TImageData;
beginRadius := (Size + 1) shr 1; // 图像边框扩展半径Angle := PI * Angle / 180;Size := Size shl 12;        // Size = Size * 256Num := (Num shl 9) div 100; // Num *= 5.12 转换为2的幂xDelta := Round(Cos(Angle) * Size);yDelta := Round(Sin(Angle) * Size);x := (Radius shl 12) - (xDelta div 2);y := (Radius shl 12) - (yDelta div 2);width := x + (Data.Width shl 12);height := y + (Data.Height shl 12);if Data.AlphaFlag thenArgbConvertPArgb(Data);src := _GetExpandData(Data, Radius);asmmov       eax, Datalea       edx, srccall      _SetCopyRegsmov       dstOffset, ebxmovq      mm5, qword ptr ArgbTab[128*8]// mm5 = 00 128 00 128 00 128 00 128movd      mm6, Num        // mm6 = 00 Num 00 Num 00 Num 00 Numpunpcklwd mm6, mm6punpcklwd mm6, mm6pxor      mm7, mm7        // mm7 = 00 00 00 00 00 00 00 00pxor      xmm7, xmm7mov       esi, src.Scan0mov       ebx, src.Stridemov       ecx, y          // for (; y < Height; y += 4096)
@@yLoop:                      // {mov         edx, x          //   for (; x < Width; x += 4096)
@@xLoop:                      //   {add       ecx, yDelta     //     y1 = y + yDeltaadd       edx, xDelta     //     x1 = x + xDeltacall      GetSrcColor     //movq      mm1, mm0        //     mm1 = 00 A1 00 R1 00 G1 00 B1sub       ecx, yDelta     //     y0 = y - yDeltasub       edx, xDelta     //     x0 = x - xDeltacall      GetSrcColor     //     mm0 = 00 A0 00 R0 00 G0 00 B0psubw     mm0, mm1        //     mm0 = A0-A1 R0-R1 G0-G1 B0-B1psllw     mm0, 7          //     mm0 = mm0 * 128 * Num / 65536pmulhw    mm0, mm6paddw     mm0, mm5        //     mm0 = A+128 R+128 G+128 B+128packuswb  mm0, mm7        //     mm0 = 00 00 00 00 A R G Bmov       al, [edi].TARGBQuad.Alphamovd      [edi], mm0      //     *edi = mm0mov       [edi].TARGBQuad.Alpha, aladd       edi, 4          //     edi += 4add       edx, 1000hcmp       edx, widthjl        @@xLoop         //   }add       ecx, 1000hadd       edi, dstOffsetcmp       ecx, heightjl        @@yLoop         // }emmsend;FreeImageData(src);if Data.AlphaFlag thenPArgbConvertArgb(Data);
end;

下面是个演示例子代码:

procedure TForm1.Button3Click(Sender: TObject);
varbmp: TGpBitmap;g: TGpGraphics;data: TImageData;
beginbmp := TGpBitmap.Create('..\media\20041001.jpg');g := TGpGraphics.Create(Canvas.Handle);g.DrawImage(bmp, 0, 0);data := LockGpBitmap(bmp);ImageGraySculpture(data, 45, 3, 100);UnlockGpBitmap(bmp, data);g.DrawImage(bmp, 0, data.Height);g.Free;bmp.Free;
end;

运行效果图:

和Photoshop浮雕效果对比,基本一致。

补记:在文章评论中,有人说灰色浮雕不带彩,其实是不正确的,我测试过网上和书上的很多代码,也测试过Photoshop,都是有可能带彩的,在浮雕深度很小而且原始图像色彩较平淡时也有可能不带彩,可以把我上面的原图裁下来,用Photoshop一试就清楚了。当然,如果你要达到完全不带彩也很简单,在浮雕处理前做一个图像灰度化即可。如果灰度浮雕完全不带彩,程序代码可得到简化,速度至少可再提高60%以上。

《Delphi图像处理》系列使用GDI+单元下载地址和说明见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。

    因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:maozefa@hotmail.com

这里可访问《Delphi图像处理 -- 文章索引》。

Delphi图像处理 -- 灰色浮雕相关推荐

  1. Delphi图像处理 -- 彩色浮雕

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  2. Delphi图像处理 -- 高保真反差

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  3. Delphi图像处理 -- 图像合成

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  4. Delphi图像处理 -- 最大值

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  5. Delphi图像处理 -- USM锐化

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  6. Delphi图像处理 -- 图像翻转(镜像)

    阅读提示:     <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM.     <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...

  7. delphi 图像处理 图像左旋右旋

    procedure TDR_QM_ZP_Form.btn_ZXClick(Sender: TObject); //图像左旋 beginscreen.Cursor := crhourglass;my_i ...

  8. 077_《Delphi数字图像处理及高级应用》

    <Delphi数字图像处理及高级应用> Delphi 教程 系列书籍 (077) <Delphi数字图像处理及高级应用> 网友(邦)整理 EMail: shuaihj@163. ...

  9. python调整图片大小不覆盖exif_python---基础知识回顾(十一)图像处理模块PIL

    前戏: 虽然PIL没有入OpenCV那样强大的功能,但是所提供的功能,在一般的图像处理中足够使用. 图像类别: 计算机绘图中有两类图像:一类是矢量图,另一类是点阵图(位图) 矢量图: 基于计算机数字对 ...

最新文章

  1. Oracle的ONS创建,Oracle 10gR2 RAC Clusterware ONS服务的管理
  2. 【机器学习PAI实践十二】机器学习算法基于信用卡消费记录做信用评分
  3. linux下网口监控软件_超赞的!Aibaba技术官分享高性能Linux服务器解读笔记
  4. junit数据驱动测试_使用Junit和Easytest进行数据驱动的测试
  5. rsync软件配置和使用教程
  6. 【转】SQLite3简介及在.Net程序中的使用(自增列的创建)
  7. 常用的做网站软件、网站制作软件分享
  8. 华为网络技术大赛模拟题目
  9. MEGA这个网盘你可以拥有,超级良心
  10. catia中的螺旋伞齿轮画法_CATIA齿轮绘制方法
  11. [转]软件安装管家软件安装目录
  12. 揭露富爸爸背后真正的秘密
  13. python电影爬虫背景介绍_Python爬虫入门教程01之爬取豆瓣Top电影
  14. 【微信小程序】几个常用小功能
  15. C语言求Fibonacci数列
  16. iOS - 个人中心果冻弹性下拉动画
  17. Linux命令之压缩zip
  18. 老照片在哪里可以修复?安利几款实用的修复软件
  19. FFmpeg的那些坑-RTP missed xxx packets
  20. 微信小程序抓包反编译保姆级教程

热门文章

  1. wex5 实战 常用代码模型集合
  2. 【Lintcode】1375. Substring With At Least K Distinct Characters
  3. 解决undefined reference to symbol ‘LZ4_decompress_safe‘问题
  4. python 堆叠柱状图 多列 复杂_[Python Study Notes]堆叠柱状图绘制
  5. 冰箱变革成AI科技营养管家 COLMO 成功占位营养及高定赛道
  6. Android4.0 ext disk auto mount [including sd mmc sata udisk]
  7. excel自定义格式分钟计时_巧用EXCEL制作计时器
  8. PhotoShop 切片、标尺使用
  9. 【h5移动端页面调起手机sms批量发送短信,兼容ios和android】
  10. ORACLE ORDER BY的多种排序