Delphi 汇编学习(九)--- 图像透明度调节的极致优化

17 篇文章 4 订阅
15 篇文章 2 订阅

图像的透明度,其实就是两幅图像的占比。
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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值