图像的透明度,其实就是两幅图像的占比。
R = R1 * (1 - K)+ R2 * K
G = G1 * (1 - K)+ G2 * K
B = B1 * (1 - K)+ B2 * K
K 在 0.0 --- 1.0 之间。
这里有浮点乘法运算,当然我们可以进行整点优化。
标准函数:
procedure ColorTrans_Scanline(bmpDst, bmpSrc: TBitmap; const intTransValue: Integer);
var
X, Y : Integer;
iLeft, iTop: Integer;
pColorDst : PRGBQuad;
pColorSrc : PRGBQuad;
K : Integer;
begin
if bmpSrc.Width > bmpDst.Width then
Exit;
if bmpSrc.Height > bmpDst.Height then
Exit;
iTop := (bmpDst.Height - bmpSrc.Height) div 2;
iLeft := (bmpDst.Width - bmpSrc.Width) div 2;
K := (intTransValue + 1) * 256;
for Y := iTop to iTop + bmpSrc.Height - 1 do
begin
pColorDst := bmpDst.ScanLine[Y];
pColorSrc := bmpSrc.ScanLine[Y - iTop];
Inc(pColorDst, iLeft);
for X := 0 to bmpSrc.Width - 1 do
begin
pColorDst^.rgbRed := (pColorDst^.rgbRed * (65536 - K) + pColorSrc^.rgbRed * K) shr 16;
pColorDst^.rgbGreen := (pColorDst^.rgbGreen * (65536 - K) + pColorSrc^.rgbGreen * K) shr 16;
pColorDst^.rgbBlue := (pColorDst^.rgbBlue * (65536 - K) + pColorSrc^.rgbBlue * K) shr 16;
Inc(pColorDst);
Inc(pColorSrc);
end;
end;
end;
4096x4096x32 的图片,在我的机器上耗时 100 毫秒左右。
并行优化版本:
{ 5 ms 需要脱离 IDE 执行 / ScanLine 不能用于 TParallel.For 中 }
procedure ColorTrans_Parallel(bmpDst, bmpSrc: TBitmap; const intTransValue: Integer);
var
iLeft, iTop : Integer;
K : Integer;
bmpWidthBytesSrc: Integer;
bmpWidthBytesDst: Integer;
StartScanLineDst: Integer;
StartScanLineSrc: Integer;
begin
if bmpSrc.Width > bmpDst.Width then
Exit;
if bmpSrc.Height > bmpDst.Height then
Exit;
iTop := (bmpDst.Height - bmpSrc.Height) div 2;
iLeft := (bmpDst.Width - bmpSrc.Width) div 2;
K := (intTransValue + 1) * 256;
StartScanLineSrc := Integer(bmpSrc.ScanLine[0]);
StartScanLineDst := Integer(bmpDst.ScanLine[iTop]);
bmpWidthBytesSrc := Integer(bmpSrc.ScanLine[1]) - Integer(bmpSrc.ScanLine[0]);
bmpWidthBytesDst := Integer(bmpDst.ScanLine[1]) - Integer(bmpDst.ScanLine[0]);
TParallel.For(0, bmpSrc.Height - 1,
procedure(Y: Integer)
var
X: Integer;
pColorDst: PRGBQuad;
pColorSrc: PRGBQuad;
begin
pColorDst := PRGBQuad(StartScanLineDst + Y * bmpWidthBytesDst);
pColorSrc := PRGBQuad(StartScanLineSrc + Y * bmpWidthBytesSrc);
Inc(pColorDst, iLeft);
for X := 0 to bmpSrc.Width - 1 do
begin
pColorDst^.rgbRed := (pColorDst^.rgbRed * (65536 - K) + pColorSrc^.rgbRed * K) shr 16;
pColorDst^.rgbGreen := (pColorDst^.rgbGreen * (65536 - K) + pColorSrc^.rgbGreen * K) shr 16;
pColorDst^.rgbBlue := (pColorDst^.rgbBlue * (65536 - K) + pColorSrc^.rgbBlue * K) shr 16;
Inc(pColorDst);
Inc(pColorSrc);
end;
end);
end;
4096x4096x32 的图片,和 2048x2048x32 的图片透明叠加,在我的机器上耗时 5 毫秒左右。
4096x4096x32 的图片,和 4096x4096x32 的图片透明叠加,在我的机器上耗时 10 毫秒左右。
非常的理想了,无需进行 SSE 优化了。
详细代码:https://github.com/dbyoung720/ImageGray.git
qq交流群:101611228