delphibitmapvcldelphi-2007scanline

How to "flush" changes to a bitmap's ScanLine


I'm currently trying to add mirroring to our RotateBitmap routine (from http://www.efg2.com/Lab/ImageProcessing/RotateScanline.htm). This currently looks like this (BitMapRotated is a TBitmap) in pseudo-code:

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;

This works if I either must rotate or reflect. If I do both then apparently the call to SetSize invalidates my previous changes via ScanLine. How can I "flush" or save my changes? I tried calling BitmapRotated.Handle, BitmapRotated.Dormant and setting BitmapRotated.Canvas.Pixels[0, 0] but without luck.

Edit: I found the real issue - I'm overwriting my changes with values from the original bitmap. Sorry for the effort.


Solution

  • Perhaps this is not really an answer, but this code works in both D2006 and XE3 and gives the expected result. There is no need to 'flush' anything.

    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);