如何“刷新”位图的ScanLine的更改

时间:2013-06-28 10:26:40

标签: delphi bitmap vcl delphi-2007 scanline

我目前正在尝试为我们的RotateBitmap例程添加镜像(来自http://www.efg2.com/Lab/ImageProcessing/RotateScanline.htm)。目前在伪代码中看起来像这样(BitMapRotated是TBitmap):

var
  RowRotatedQ: pRGBquadArray; //4 bytes

if must reflect then
begin
  for each j do
  begin
    RowRotatedQ := BitmapRotated.Scanline[j];
    manipulate RowRotatedQ
  end;
end;

if must rotate then
begin
  BitmapRotated.SetSize(NewWidth, NewHeight); //resize it for rotation
  ...
end;

如果 必须旋转反映,则此方法有效。如果我同时执行这两项操作,那么显然对SetSize的调用会使我之前通过ScanLine进行的更改无效。我怎样才能"冲洗"或保存我的更改?我尝试拨打BitmapRotated.HandleBitmapRotated.Dormant并设置BitmapRotated.Canvas.Pixels[0, 0],但没有运气。

编辑:我发现了真实问题 - 我用原始位图中的值覆盖了我的更改。很抱歉。

1 个答案:

答案 0 :(得分:1)

也许这不是一个真正的答案,但这个代码适用于D2006和XE3,并给出了预期的结果。没有必要“冲洗”任何东西。

enter image description here

  procedure RotateBitmap(const BitMapRotated: TBitmap);
  type
    PRGBQuadArray = ^TRGBQuadArray;
    TRGBQuadArray = array [Byte] of TRGBQuad;
  var
    RowRotatedQ: PRGBQuadArray;
    t: TRGBQuad;
    ix, iy: Integer;
  begin
    //first step
    for iy := 0 to BitMapRotated.Height - 1 do begin
      RowRotatedQ := BitMapRotated.Scanline[iy];
     // make vertical mirror
      for ix := 0 to BitMapRotated.Width div 2 - 1 do begin
        t := RowRotatedQ[ix];
        RowRotatedQ[ix] := RowRotatedQ[BitMapRotated.Width - ix - 1];
        RowRotatedQ[BitMapRotated.Width - ix - 1] := t;
      end;
    end;

    //second step
    BitMapRotated.SetSize(BitMapRotated.Width  + 50, BitMapRotated.Height + 50);
    //some coloring instead of rotation
    for iy := 0 to BitMapRotated.Height div 10 do begin
      RowRotatedQ := BitMapRotated.Scanline[iy];
      for ix := 0 to BitMapRotated.Width - 1 do
        RowRotatedQ[ix].rgbRed := 0;
    end;
  end;

var
  a, b: TBitmap;
begin
  a := TBitmap.Create;
  a.PixelFormat := pf32bit;
  a.SetSize(100, 100);
  a.Canvas.Brush.Color := clRed;
  a.Canvas.FillRect(Rect(0, 0, 50, 50));
  b := TBitmap.Create;
  b.Assign(a);
  RotateBitmap(b);
  Canvas.Draw(0, 0, a);
  Canvas.Draw(110, 0, b);