设置图像关键颜色,使图像的某种或某个范围的颜色成为透明色,是图片合成、动画显示中经常用的图像处理手段。下面是实现代码:
过程定义:
// 设置色键(透明范围)。colorLow 低色键值; colorHigh 高色键值
// 当像素A、R、G、B值同时大于等于colorLow和小于等于colorHigh时为透明色
procedure ImageSetColorKey(Data: TImageData; ColorLow, ColorHigh: LongWord);
// 按坐标颜色设置色键。x,y 图像坐标点, Precision 色键容差
procedure ImageSetColorKeyPoint(Data: TImageData; x, y: Integer; Precision: LongWord);
实现代码:
procedure ImageSetColorKey(Data: TImageData; ColorLow, ColorHigh: LongWord);
procedure ColorKeyEQ(Data: TImageData; ColorKey: LongWord);
asm
punpckldq mm2, mm2 // mm2 = ColorKey ColorKey
mov eax, ecx
shr ecx, 1 // 每次比较2个像素
@yLoop:
push ecx
@xLoop:
dec ecx
js @@1
movq mm0, [edi] // mm0 = A1 R1 G1 B1 A0 R0 G0 B0
pcmpeqd mm0, mm2 // 按32位数对2个像素进行比较
pandn mm0, [edi] // 比较结果取非后同原象素值作与运算
movq [edi], mm0 // 存入结果
add edi, 8
jmp @xLoop
@@1:
test eax, 1 // 比较可能存在的最后一个像素
jz @@2
movd mm0, [edi]
pcmpeqd mm0, mm2
movd ecx, mm0
not ecx
and [edi], ecx
add edi, 4
@@2:
pop ecx
add edi, ebx
dec edx
jnz @yLoop
end;
procedure ColorKeyArea(Data: TImageData; ColorLow, ColorHigh: LongWord);
asm
pxor mm7, mm7 // 比较命令是按有符号数进行的,因此
punpcklbw mm2, mm7 // ColorLow按字节扩展为字
punpcklbw mm3, mm7 // ColorHigh按字节扩展为字
@yLoop:
push ecx
@xLoop:
movd mm0, [edi] // mm0 = 00 00 00 00 A R G B
punpcklbw mm0, mm7 // mm0 = 00 A 00 R 00 G 00 B
movq mm1, mm2
pcmpgtw mm1, mm0 // 比较 ColorLow 是否大于 mm0