首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 平面设计 > 图形图像 >

Delphi图像处理 - 表面模糊

2012-08-13 
Delphi图像处理 -- 表面模糊阅读提示:《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用

Delphi图像处理 -- 表面模糊

阅读提示:

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

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

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

   本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程// ARGB图像数据表面模糊处理.// 参数: 图像数据, 模糊半径, 阈值procedure SurfaceBlur(var Data: TImageData; Radius, Threshold: Integer);const _fc2_5: Single = 2.5;var width, height, size: Integer; srcOffset, dstOffset: Integer; src: TImageData;begin if not (Radius in [1..100]) or not (Threshold in [2..255]) then Exit; if Data.AlphaFlag then // 如果图像数据含Alpha信息, 转换为PARGB格式 ArgbConvertPArgb(Data); src := _GetExpandData(Data, Radius);// 获取扩展半径后的备份图像数据 asm push esi push edi push ebx mov eax, Data lea edx, src call _SetCopyRegs mov width, ecx mov height, edx mov srcOffset, eax mov dstOffset, ebx mov eax, src.Stride mov ebx, Radius shl ebx, 1 inc ebx mov size, ebx shl ebx, 2 neg ebx add ebx, eax add eax, 4 mul Radius pxor xmm7, xmm7 cvtsi2ss xmm6, Threshold // xmm6 = 4 * (Threshold * 2.5) movss xmm0, _fc2_5 mulss xmm6, xmm0 pshufd xmm6, xmm6, 0@@yLoop: push width@@xLoop: push esi mov edx, Size pxor xmm0, xmm0 // Total Pixels pxor xmm5, xmm5 // Nuclear movd xmm4, [esi+eax] // xmm4 = p0 = 4 * word(a,r,g,b) punpcklbw xmm4, xmm7@@iLoop: mov ecx, Size@@jLoop: movd xmm1, [esi] punpcklbw xmm1, xmm7 movaps xmm3, xmm1 // 计算模糊矩阵元素值 psubw xmm1, xmm4 // xmm1 = pij - p0 (+) pxor xmm2, xmm2 psubw xmm2, xmm1 // xmm2 = pij - p0 (-) 零减xmm1实现各分量差值的正负转换 packuswb xmm1, xmm7 // 字节饱和去掉xmm1中各分量差值中的负值 packuswb xmm2, xmm7 // 字节饱和去掉xmm2中各分量差值中的负值 por xmm2, xmm1 // xmm2 = |pij - p0| xmm2与xmm1相或得到各分量绝对差值 punpcklbw xmm2, xmm7 punpcklwd xmm2, xmm7 cvtdq2ps xmm2, xmm2 movaps xmm1, xmm6 subps xmm1, xmm2 divps xmm1, xmm6 // xmm1 = ((xmm6 - xmm2) / xmm6) maxps xmm1, xmm7 // 去掉xmm1中的负值 // 累计模糊矩阵元素值 addps xmm5, xmm1 // Nuclear += xmm1 punpcklwd xmm3, xmm7 cvtdq2ps xmm3, xmm3 mulps xmm1, xmm3 // xmm1 *= (ARGB)ij // 累计模糊矩阵元素值与对应像素的乘积 addps xmm0, xmm1 // Total Pixels += xmm1 add esi, 4 loop @@jLoop add esi, ebx dec edx jnz @@iLoop divps xmm0, xmm5 // p0 = Total Pixels /= Nuclear cvtps2dq xmm0, xmm0 packssdw xmm0, xmm7 packuswb xmm0, xmm7 movd [edi], xmm0 pop esi add esi, 4 add edi, 4 dec width jnz @@xLoop pop width add esi, srcOffset add edi, dstOffset dec height jnz @@yLoop pop ebx pop edi pop esi end; FreeImageData(src); if Data.AlphaFlag then // 如果图像数据含Alpha信息, 还原为ARGB格式 PArgbConvertArgb(Data);end;

    表面模糊处理过程中使用了SSE代码,以同时处理ARGB4个分量值。

    下面是个简单应用例子:

    例子运行效果截图:

Delphi图像处理 - 表面模糊

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

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

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