0

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.

Uli Gerhardt
  • 13,748
  • 1
  • 45
  • 83
  • why not using readymade libs like Graphics32.org or Vampyre Imaging? – Arioch 'The Jun 28 '13 at 10:31
  • I would simply have an output bitmap. Anyway, [`this Q&A`](http://stackoverflow.com/a/10633410/960757) might be interesting for your task. – TLama Jun 28 '13 at 10:42
  • @Arioch'The: We're already using this routine and it seemed like an easy task to extend it. – Uli Gerhardt Jun 28 '13 at 10:56
  • @TLama: IIUYC `BitmapRotated` already **is** the output bitmap. The routine is declared `procedure RotateBitmap( const BitmapOriginal: TBitmap; // input bitmap (possibly converted) const BitMapRotated: TBitmap; // output bitmap ...` – Uli Gerhardt Jun 28 '13 at 10:59

1 Answers1

1

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);
MBo
  • 77,366
  • 5
  • 53
  • 86