Recent

Author Topic: Inconsistent behaviour of copyrect in Windows and Linux  (Read 1114 times)

han

  • Jr. Member
  • **
  • Posts: 58
Inconsistent behaviour of copyrect in Windows and Linux
« on: April 23, 2018, 10:47:40 am »
I’m working on an application which should flip images with pixel accuracy. This is possible with copyrect. I can do the following for a horizontal flip:

Code: Pascal  [Select]
  1. src:=rect(w, 0, 0, h);
  2. dest:=bounds(0, 0, w, h); //horizontal flip
  3. ...
  4. ...
  5. image1.Picture.Bitmap.Canvas.CopyRect(dest, bmp.Canvas, src);


However this doesn’t work for Linux (1). To make it work if I have to do the following:
Code: Pascal  [Select]
  1. src:=rect(0, 0, w, h);
  2. dest:=rect(w, 0, 0, h);//horizontal flip

This works fine in Linux and Windows, however in Windows it is shifted one pixel (2)!!!
To prevent the shift in Windows I have to do the following:
Code: Pascal  [Select]
  1. src:=rect(0, 0, w, h);
  2. {$ifdef mswindows}
  3. dest:=rect(w-1, 0, 0-1, h);//horizontal flip.
  4. {$else} {unix}
  5. dest:=rect(w, 0, 0, h);//horizontal flip
  6. {$endif}

or better

Code: Pascal  [Select]
  1. {$ifdef mswindows}
  2. src:=rect(w, 0, 0, h); {doesn't work in Linux, why?}
  3. dest:=rect(0, 0, w, h);
  4. {$else} {unix}
  5. src:=rect(0, 0, w, h);
  6. dest:=rect(w, 0, 0, h);//horizontal flip, but gives in Windows one pixel drift.
  7. {$endif}


Any idea why the Linux version and Windows version behave different on these two points (1) and (2)?

See attached test program. Watch the white pixels at the corners. These should be one pixel away from the corners. Note the image is stretched.

For vertical flip the same problem. This is my solution:
Code: Pascal  [Select]
  1. {$ifdef mswindows}
  2. src:=rect(0, h, w, 0); // Vertical flip, works for windows but not Linux
  3. dest:=rect(0, 0, w, h);
  4. {$else} {unix}
  5. src:=rect(0, 0, w, h);
  6. dest:=rect(0,h, w, 0);//vertical flip, works for Linux but gives in Windows one pixel drift.
  7. {$endif}


The full procedure:

Code: Pascal  [Select]
  1. procedure TForm1.fliphorizontal1Click(Sender: TObject);
  2. var src, dest: TRect;
  3.     bmp: TBitmap;
  4.     w, h: integer;
  5. begin
  6.   w:=image1.Picture.Width; h:=image1.Picture.Height;
  7.  
  8.   {$ifdef mswindows}
  9.   src:=rect(w, 0, 0, h); {doesn't work in Linux, why?}
  10.   dest:=bounds(0, 0, w, h);
  11.   {$else} {unix}
  12.   src:=rect(0, 0, w, h);
  13.   dest:=rect(w, 0, 0, h);//horizontal flip, but gives one pixel shift in Windows
  14.   {$endif}
  15.  
  16.   bmp:=TBitmap.Create;
  17.   bmp.PixelFormat:=pf24bit;
  18.  
  19.   bmp.SetSize(w, h);
  20.   bmp.Canvas.Draw(0, 0, image1.Picture.Bitmap);
  21.   image1.Picture.Bitmap.Canvas.CopyRect(dest, bmp.Canvas, src);
  22.   bmp.Free;
  23. end;
« Last Edit: April 23, 2018, 12:38:25 pm by han »