Răsfoiți Sursa

CropArea Rotate and Flip

Massimo Magnano 2 ani în urmă
părinte
comite
cb3174d358

+ 180 - 2
bgraimagemanipulation.pas

@@ -72,6 +72,7 @@ unit BGRAImageManipulation;
              - XML Use Laz2_XMLCfg in fpc
              - divide by zero in getImageRect on Component Loading
              - EmptyImage size to ClientRect when Width/Height=0; Mouse Events when Image is Empty
+             - CropArea Rotate and Flip
   ============================================================================
 }
 
@@ -185,14 +186,14 @@ type
 
     procedure Render_Refresh;
 
-    { #note 2 -oMaxM : all the Code that use Resolution may be under if BGRABitmapVersion > 11050400 }
     procedure GetImageResolution(var resX, resY:Single; var resUnit:TResolutionUnit);
     procedure CalculateScaledAreaFromArea;
     procedure CalculateAreaFromScaledArea;
     function GetPixelArea(const AValue: TRectF):TRect;
 
-    property ScaledArea :TRect read rScaledArea write setScaledArea;
+    procedure CheckOutOfBounds(var AArea:TRect);
 
+    property ScaledArea :TRect read rScaledArea write setScaledArea;
   public
     Rotate   :double;
     UserData :Integer;
@@ -213,6 +214,14 @@ type
     procedure BringForward;
     procedure BringBackward;
 
+    //Rotate/Flip
+    procedure RotateLeft;
+    procedure RotateRight;
+    procedure FlipHLeft;
+    procedure FlipHRight;
+    procedure FlipVUp;
+    procedure FlipVDown;
+
     property Area:TRectF read rArea write setArea;
     property AreaUnit:TResolutionUnit read rAreaUnit write setAreaUnit;
     property Top:Single read getTop write setTop;
@@ -254,6 +263,14 @@ type
     procedure SaveToStream(Stream: TStream);
     procedure SaveToFile(const FileName: string);
 
+    //Rotate/Flip
+    procedure RotateLeft;
+    procedure RotateRight;
+    procedure FlipHLeft;
+    procedure FlipHRight;
+    procedure FlipVUp;
+    procedure FlipVDown;
+
     property items[aIndex: integer] : TCropArea read getCropArea write setCropArea; default;
     property Name:String read rName write rName;
   end;
@@ -837,6 +854,41 @@ begin
     end;
 end;
 
+procedure TCropArea.CheckOutOfBounds(var AArea:TRect);
+var
+   tmpValue: Integer;
+
+begin
+  //Out of Bounds check
+  if (AArea.Left<0)
+  then begin
+         tmpValue :=-AArea.Left;
+         AArea.Left :=0;
+         AArea.Right:=AArea.Right+tmpValue;
+       end;
+
+  if (AArea.Top<0)
+  then begin
+         tmpValue :=-AArea.Top;
+         AArea.Top :=0;
+         AArea.Bottom:=AArea.Bottom+tmpValue;
+       end;
+
+  if (AArea.Right>fOwner.fResampledBitmap.Width)
+  then begin
+         tmpValue :=AArea.Right-fOwner.fResampledBitmap.Width;
+         AArea.Right :=fOwner.fResampledBitmap.Width;
+         AArea.Left:=AArea.Left-tmpValue; //if <0 ? a vicious circle
+       end;
+
+  if (AArea.Bottom>fOwner.fResampledBitmap.Height)
+  then begin
+         tmpValue :=AArea.Bottom-fOwner.fResampledBitmap.Height;
+         AArea.Bottom :=fOwner.fResampledBitmap.Height;
+         AArea.Top:=AArea.Top-tmpValue; //if <0 ? a vicious circle
+       end;
+end;
+
 procedure TCropArea.CopyAspectFromParent;
 begin
   rAspectX :=fOwner.fAspectX;
@@ -1260,6 +1312,84 @@ begin
   end;
 end;
 
+procedure TCropArea.RotateLeft;
+var
+   newArea :TRect;
+
+begin
+  newArea.Right :=rScaledArea.Left;
+  newArea.Bottom:=rScaledArea.Bottom;
+  newArea.Left:=newArea.Right-rScaledArea.Height;
+  newArea.Top:=newArea.Bottom-rScaledArea.Width;
+  CheckOutOfBounds(newArea);
+  ScaledArea :=newArea;
+end;
+
+procedure TCropArea.RotateRight;
+var
+   newArea :TRect;
+
+begin
+  newArea.Left :=rScaledArea.Right;
+  newArea.Bottom:=rScaledArea.Bottom;
+  newArea.Right:=newArea.Left+rScaledArea.Height;
+  newArea.Top:=newArea.Bottom-rScaledArea.Width;
+  CheckOutOfBounds(newArea);
+  ScaledArea :=newArea;
+end;
+
+procedure TCropArea.FlipHLeft;
+var
+   newArea :TRect;
+
+begin
+  newArea.Top:=rScaledArea.Top;
+  newArea.Bottom:=rScaledArea.Bottom;
+  newArea.Right :=rScaledArea.Left;
+  newArea.Left:=newArea.Right-rScaledArea.Width;
+  CheckOutOfBounds(newArea);
+  ScaledArea :=newArea;
+end;
+
+procedure TCropArea.FlipHRight;
+var
+   newArea :TRect;
+
+begin
+  newArea.Top:=rScaledArea.Top;
+  newArea.Bottom:=rScaledArea.Bottom;
+  newArea.Left :=rScaledArea.Right;
+  newArea.Right:=newArea.Left+rScaledArea.Width;
+  CheckOutOfBounds(newArea);
+  ScaledArea :=newArea;
+end;
+
+procedure TCropArea.FlipVUp;
+var
+   newArea :TRect;
+
+begin
+  newArea.Left:=rScaledArea.Left;
+  newArea.Right:=rScaledArea.Right;
+  newArea.Bottom :=rScaledArea.Top;
+  newArea.Top:=newArea.Bottom-rScaledArea.Height;
+  CheckOutOfBounds(newArea);
+  ScaledArea :=newArea;
+end;
+
+procedure TCropArea.FlipVDown;
+var
+   newArea :TRect;
+
+begin
+  newArea.Left:=rScaledArea.Left;
+  newArea.Right:=rScaledArea.Right;
+  newArea.Top :=rScaledArea.Bottom;
+  newArea.Bottom:=newArea.Top+rScaledArea.Height;
+  CheckOutOfBounds(newArea);
+  ScaledArea :=newArea;
+end;
+
 { TCropAreaList }
 
 procedure TCropAreaList.setLoading(AValue: Boolean);
@@ -1478,6 +1608,54 @@ begin
   end;
 end;
 
+procedure TCropAreaList.RotateLeft;
+var
+   i :Integer;
+
+begin
+  for i:=0 to Count-1 do Items[i].RotateLeft;
+end;
+
+procedure TCropAreaList.RotateRight;
+var
+   i :Integer;
+
+begin
+  for i:=0 to Count-1 do Items[i].RotateRight;
+end;
+
+procedure TCropAreaList.FlipHLeft;
+var
+   i :Integer;
+
+begin
+  for i:=0 to Count-1 do Items[i].FlipHLeft;
+end;
+
+procedure TCropAreaList.FlipHRight;
+var
+   i :Integer;
+
+begin
+  for i:=0 to Count-1 do Items[i].FlipHRight;
+end;
+
+procedure TCropAreaList.FlipVUp;
+var
+   i :Integer;
+
+begin
+  for i:=0 to Count-1 do Items[i].FlipVUp;
+end;
+
+procedure TCropAreaList.FlipVDown;
+var
+   i :Integer;
+
+begin
+  for i:=0 to Count-1 do Items[i].FlipVDown;
+end;
+
 { TBGRAEmptyImage }
 
 function TBGRAEmptyImage.getHeight: Integer;

+ 303 - 25
test/test_bgraimagemanipulation/unitbgraimagemanipulationdemo.lfm

@@ -1,10 +1,10 @@
 object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
   Left = 261
-  Height = 480
+  Height = 513
   Top = 125
   Width = 898
   Caption = 'Demonstration of TBGRAImageManipulation'
-  ClientHeight = 480
+  ClientHeight = 513
   ClientWidth = 898
   OnCloseQuery = FormCloseQuery
   OnCreate = FormCreate
@@ -12,7 +12,7 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
   LCLVersion = '3.99.0.0'
   object Background: TBCPanel
     Left = 650
-    Height = 480
+    Height = 513
     Top = 0
     Width = 248
     Align = alRight
@@ -1605,7 +1605,7 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
   end
   object BGRAImageManipulation: TBGRAImageManipulation
     Left = 170
-    Height = 480
+    Height = 513
     Top = 0
     Width = 480
     Align = alClient
@@ -1627,7 +1627,7 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
   end
   object BCPanelCropAreas: TBCPanel
     Left = 0
-    Height = 480
+    Height = 513
     Top = 0
     Width = 170
     Align = alLeft
@@ -1714,7 +1714,7 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
     object BCPanelCropAreaLoad: TBCPanel
       Left = 1
       Height = 106
-      Top = 373
+      Top = 406
       Width = 168
       Align = alBottom
       Background.Color = clBtnFace
@@ -2198,7 +2198,7 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
     end
     object BCPanelCropArea: TBCPanel
       Left = 0
-      Height = 320
+      Height = 360
       Top = 48
       Width = 170
       Background.Color = clBtnFace
@@ -2459,17 +2459,17 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         TabOrder = 1
       end
       object edAspectPersonal: TEdit
-        Left = 47
+        Left = 45
         Height = 23
-        Top = 298
+        Top = 330
         Width = 87
         AutoSize = False
         TabOrder = 2
       end
       object rgAspect: TRadioGroup
-        Left = 22
-        Height = 76
-        Top = 216
+        Left = 20
+        Height = 68
+        Top = 256
         Width = 137
         AutoFill = True
         Caption = 'Aspect Ratio'
@@ -2480,7 +2480,7 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         ChildSizing.ShrinkVertical = crsScaleChilds
         ChildSizing.Layout = cclLeftToRightThenTopToBottom
         ChildSizing.ControlsPerLine = 1
-        ClientHeight = 56
+        ClientHeight = 48
         ClientWidth = 133
         Items.Strings = (
           'Parent'
@@ -2491,9 +2491,9 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         TabOrder = 3
       end
       object btApplyAspectRatio: TSpeedButton
-        Left = 135
+        Left = 133
         Height = 22
-        Top = 299
+        Top = 331
         Width = 23
         Glyph.Data = {
           C6070000424DC607000000000000360000002800000016000000160000000100
@@ -2623,17 +2623,17 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         Value = 50
       end
       object Label1: TLabel
-        Left = 8
+        Left = 7
         Height = 15
-        Top = 176
+        Top = 224
         Width = 46
         Caption = 'Z Order :'
       end
       object btZFront: TSpeedButton
-        Left = 58
+        Left = 57
         Height = 22
         Hint = 'To Front'
-        Top = 176
+        Top = 224
         Width = 23
         Glyph.Data = {
           36040000424D3604000000000000360000002800000010000000100000000100
@@ -2674,10 +2674,10 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         OnClick = btZFrontClick
       end
       object btZBack: TSpeedButton
-        Left = 82
+        Left = 81
         Height = 22
         Hint = 'To Back'
-        Top = 176
+        Top = 224
         Width = 23
         Glyph.Data = {
           36040000424D3604000000000000360000002800000010000000100000000100
@@ -2718,10 +2718,10 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         OnClick = btZBackClick
       end
       object btZDown: TSpeedButton
-        Left = 135
+        Left = 134
         Height = 22
         Hint = 'Down'
-        Top = 176
+        Top = 224
         Width = 23
         Glyph.Data = {
           36040000424D3604000000000000360000002800000010000000100000000100
@@ -2762,10 +2762,10 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         OnClick = btZDownClick
       end
       object btZUp: TSpeedButton
-        Left = 111
+        Left = 110
         Height = 22
         Hint = 'Up'
-        Top = 176
+        Top = 224
         Width = 23
         Glyph.Data = {
           36040000424D3604000000000000360000002800000010000000100000000100
@@ -2805,6 +2805,284 @@ object FormBGRAImageManipulationDemo: TFormBGRAImageManipulationDemo
         }
         OnClick = btZUpClick
       end
+      object Label2: TLabel
+        Left = 14
+        Height = 15
+        Top = 176
+        Width = 40
+        Caption = 'Rotate :'
+      end
+      object btCRotateLeft: TSpeedButton
+        Left = 58
+        Height = 22
+        Hint = 'Rotate Left'
+        Top = 176
+        Width = 23
+        Glyph.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF0000820015068E039300000001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000480
+          003A1E9A1AF22CA529FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000480026F1F9D
+          1EFB07AD07FE18AB16FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00008000010C8209A71B9719FC01A4
+          01FF00BA00FF15B413FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00007100140F7D0DD4118210FB008F00FF00A5
+          00FF00BB00FF11B00FFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000561003610700EED096809FB007500FF008A00FF009D
+          00FF00AE00FF0DA40CFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00035E00550E5C0DF8034703FE015B01FF026F02FF007F00FF0090
+          00FF009D00FF0A9609FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00005900521F671FF9397639FE337E33FF2F872FFF2D922DFF2799
+          27FF239E23FF1C931CFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF0000520032196618EB468746FC479447FF439943FF3E9D
+          3EFF3A9F3AFF248D24FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00004400120F5C0FCB4F934FFC5BA45BFF57A5
+          57FF52A552FF2D892DFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000800001075307994F8E4FFC70B3
+          70FF6BB16BFF3A853AFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00004E00604381
+          43F983C083FE458545FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000048
+          0032327032ED4A844AFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF0000420012004E008700000001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+        }
+        OnClick = btCRotateLeftClick
+      end
+      object btCRotateRight: TSpeedButton
+        Left = 82
+        Height = 22
+        Hint = 'Rotate Right'
+        Top = 176
+        Width = 23
+        Glyph.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF0006890351078A0366FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00159611BE2EA92CFF118F0CAC00800001FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF0013920FBB0BBC0BFF17B116FB159112D800770015FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000F8D0CB809D509FF00C500FF0CB00CFC169214F00575
+          0038FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000E880BB508D008FF00C400FF00B000FF059B05FE027E
+          00F90272006BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000C8209B106BB06FF00B400FF00A600FF009400FF007F
+          00FF127A11FB086F06A200800001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00077C06AF04A604FF00A100FF009700FF018801FF0378
+          03FF006300FF0A5C0AFB086608CC00000001FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00057404AC2AA52AFF25A325FF2AA02AFF2E992EFF3190
+          31FF368836FF327A32FC0D630CCB00000001FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00036C02A93EA43EFF3CA23CFF40A240FF459E45FF499A
+          49FF327F32FB0559059900800001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00006200A655A855FF55A955FF59A959FF5CA75CFE2D78
+          2DF900500060FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00005700A66DB36DFF6DB46DFF6BAF6BFD236B23EB0049
+          0031FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00004E00A685C185FF70AC70FD195F19CD00440012FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00004E00A67BAD7BFE0D570D9B00800001FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00004F004A0852085CFFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+        }
+        OnClick = btCRotateRightClick
+      end
+      object Label3: TLabel
+        Left = 28
+        Height = 15
+        Top = 200
+        Width = 25
+        Caption = 'Flip :'
+      end
+      object btCFlipVUp: TSpeedButton
+        Left = 58
+        Height = 22
+        Hint = 'Flip Vertical Up'
+        Top = 200
+        Width = 23
+        Glyph.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
+          0001005000090050000900500009005000090050000900500009005000090050
+          00090050000900500009005000090050000900000001FFFFFF00FFFFFF00004D
+          00854A844AFF458545FF3A853AFF2D892DFF258D25FF1C931CFF0A9609FF0DA4
+          0CFF11B00FFF15B413FF18AB16FF29A427FF068E039BFFFFFF00FFFFFF000042
+          0012327032ED83C083FE6BB16BFF52A552FF3A9F3AFF259F25FF009D00FF00AE
+          00FF00BB00FF00BA00FF05AC05FE1A9616F300870019FFFFFF00FFFFFF00FFFF
+          FF0000480032418041F970B370FF57A557FF3E9D3EFF2A9A2AFF009000FF009D
+          00FF00A500FF00A400FF038E00FB04830044FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00004E00614D8C4DFC5BA45BFF439943FF2D932DFF028002FF008A
+          00FF008F00FF179515FC067F0277FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00055205984E924EFC479447FF2F872FFF067106FF0075
+          00FF0E810DFB0C8109AEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00008000010D5A0DCB468946FC347F34FF055D05FF0767
+          07FB0D7D0BD800800001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF0000420012166215EB387638FE044804FE0E71
+          0CF0006E0018FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00005100341E631DF91B661AFA0465
+          003EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000580053337F3064FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+        }
+        OnClick = btCFlipVUpClick
+      end
+      object btCFlipVDown: TSpeedButton
+        Left = 82
+        Height = 22
+        Hint = 'Flip Vertical Down'
+        Top = 200
+        Width = 23
+        Glyph.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000058005303610058FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00005100341E6A1DF90C620BFA0465
+          003EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF0000420012166715EB388238FE045D04FE0E76
+          0CF0006E0018FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00008000010D5D0DCB469246FC348C34FF057005FF077A
+          07FB0D7F0BD800800001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00055205984E974EFC479C47FF2F942FFF068206FF008A
+          00FF0E920DFB0C8109AEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00004E00614D904DFC5BA95BFF43A043FF2D9D2DFF029102FF009D
+          00FF00A500FF17A015FC067F0277FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF0000480032418141F970B670FF57A957FF3EA33EFF2AA22AFF009D00FF00AE
+          00FF00BA00FF00BA00FF1BA118FB04830044FFFFFF00FFFFFF00FFFFFF000042
+          0012327032ED83C183FE6BB26BFF52A752FF3AA23AFF25A425FF00A300FF00B8
+          00FF00CC00FF00D000FF05B805FE1A9816F300870019FFFFFF00FFFFFF00004D
+          00854A844AFF458545FF3A853AFF2D882DFF228B22FF178F17FF019000FF019E
+          00FF02A900FF02AB00FF18AA16FF28A325FF038D009AFFFFFF00FFFFFF000000
+          0001005000090050000900500009005000090050000900500009005000090050
+          00090050000900500009005000090050000900000001FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+        }
+        OnClick = btCFlipVDownClick
+      end
+      object btCFlipHLeft: TSpeedButton
+        Left = 111
+        Height = 22
+        Hint = 'Flip Horizzontal Left'
+        Top = 200
+        Width = 23
+        Glyph.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF0000820015068E039300000001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000480
+          003A1E9A1AF22CA529FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000480026F1F9D
+          1EFB07AD07FE18AB16FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00008000010C8209A71B9719FC01A4
+          01FF00BA00FF15B413FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00007100140F7D0DD4118210FB008F00FF00A5
+          00FF00BB00FF11B00FFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000561003610700EED096809FB007500FF008A00FF009D
+          00FF00AE00FF0DA40CFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00035E00550E5C0DF8034703FE015B01FF026F02FF007F00FF0090
+          00FF009D00FF0A9609FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00005900521F671FF9397639FE337E33FF2F872FFF2D922DFF2799
+          27FF239E23FF1C931CFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF0000520032196618EB468746FC479447FF439943FF3E9D
+          3EFF3A9F3AFF248D24FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00004400120F5C0FCB4F934FFC5BA45BFF57A5
+          57FF52A552FF2D892DFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000800001075307994F8E4FFC70B3
+          70FF6BB16BFF3A853AFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00004E00604381
+          43F983C083FE458545FF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000048
+          0032327032ED4A844AFF00500009FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF0000420012004E008700000001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+        }
+        OnClick = btCFlipHLeftClick
+      end
+      object btCFlipHRight: TSpeedButton
+        Left = 134
+        Height = 22
+        Hint = 'Flip Horizzontal Right'
+        Top = 200
+        Width = 23
+        Glyph.Data = {
+          36040000424D3604000000000000360000002800000010000000100000000100
+          2000000000000004000000000000000000000000000000000000FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF0006890351078A0366FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00159611BE2EA92CFF118F0CAC00800001FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF0013920FBB0BBC0BFF17B116FB159112D800770015FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000F8D0CB809D509FF00C500FF0CB00CFC169214F00575
+          0038FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000E880BB508D008FF00C400FF00B000FF059B05FE027E
+          00F90272006BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF000C8209B106BB06FF00B400FF00A600FF009400FF007F
+          00FF127A11FB086F06A200800001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00077C06AF04A604FF00A100FF009700FF018801FF0378
+          03FF006300FF0A5C0AFB086608CC00000001FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00057404AC2AA52AFF25A325FF2AA02AFF2E992EFF3190
+          31FF368836FF327A32FC0D630CCB00000001FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00036C02A93EA43EFF3CA23CFF40A240FF459E45FF499A
+          49FF327F32FB0559059900800001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00006200A655A855FF55A955FF59A959FF5CA75CFE2D78
+          2DF900500060FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00005700A66DB36DFF6DB46DFF6BAF6BFD236B23EB0049
+          0031FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00004E00A685C185FF70AC70FD195F19CD00440012FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00004E00A67BAD7BFE0D570D9B00800001FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00004F004A0852085CFFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+          FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+        }
+        OnClick = btCFlipHRightClick
+      end
     end
   end
   object OpenPictureDialog: TOpenPictureDialog

+ 92 - 0
test/test_bgraimagemanipulation/unitbgraimagemanipulationdemo.pas

@@ -76,6 +76,10 @@ type
     btApplyAspectRatio: TSpeedButton;
     btBox_Add: TBGRASpeedButton;
     btBox_Del: TBGRASpeedButton;
+    btCFlipHLeft: TSpeedButton;
+    btCFlipHRight: TSpeedButton;
+    btCFlipVUp: TSpeedButton;
+    btCFlipVDown: TSpeedButton;
     btnEmptyImage: TBCButton;
     btnLoadCropList: TBCButton;
     btnSaveCropList: TBCButton;
@@ -88,6 +92,8 @@ type
     btnSetAspectRatio: TBCButton;
     btnRotateLeft:     TBCButton;
     btnRotateRight:    TBCButton;
+    btCRotateRight: TSpeedButton;
+    btCRotateLeft: TSpeedButton;
     cbBoxList: TComboBox;
     chkFullSize: TCheckBox;
     cbSaveFormat: TComboBox;
@@ -101,6 +107,8 @@ type
     edWidth: TFloatSpinEdit;
     KeepAspectRatio:   TCheckBox;
     Label1: TLabel;
+    Label2: TLabel;
+    Label3: TLabel;
     lbResolution: TLabel;
     lbAspectRatio:     TLabel;
     lbOptions:         TLabel;
@@ -118,6 +126,12 @@ type
     btZBack: TSpeedButton;
     btZDown: TSpeedButton;
     btZUp: TSpeedButton;
+    procedure btCFlipHLeftClick(Sender: TObject);
+    procedure btCFlipHRightClick(Sender: TObject);
+    procedure btCFlipVDownClick(Sender: TObject);
+    procedure btCFlipVUpClick(Sender: TObject);
+    procedure btCRotateLeftClick(Sender: TObject);
+    procedure btCRotateRightClick(Sender: TObject);
     procedure btnEmptyImageClick(Sender: TObject);
     procedure btnGetAspectRatioFromImageClick(Sender: TObject);
     procedure btnLoadCropListClick(Sender: TObject);
@@ -250,6 +264,84 @@ begin
   end;
 end;
 
+procedure TFormBGRAImageManipulationDemo.btCRotateLeftClick(Sender: TObject);
+var
+   CropArea :TCropArea;
+
+begin
+  if (cbBoxList.ItemIndex>-1) then
+  begin
+    CropArea :=TCropArea(cbBoxList.Items.Objects[cbBoxList.ItemIndex]);
+    if CropArea<>nil
+    then CropArea.RotateLeft;
+  end;
+end;
+
+procedure TFormBGRAImageManipulationDemo.btCFlipVDownClick(Sender: TObject);
+var
+   CropArea :TCropArea;
+
+begin
+  if (cbBoxList.ItemIndex>-1) then
+  begin
+    CropArea :=TCropArea(cbBoxList.Items.Objects[cbBoxList.ItemIndex]);
+    if CropArea<>nil
+    then CropArea.FlipVDown;
+  end;
+end;
+
+procedure TFormBGRAImageManipulationDemo.btCFlipHLeftClick(Sender: TObject);
+var
+   CropArea :TCropArea;
+
+begin
+  if (cbBoxList.ItemIndex>-1) then
+  begin
+    CropArea :=TCropArea(cbBoxList.Items.Objects[cbBoxList.ItemIndex]);
+    if CropArea<>nil
+    then CropArea.FlipHLeft;
+  end;
+end;
+
+procedure TFormBGRAImageManipulationDemo.btCFlipHRightClick(Sender: TObject);
+var
+   CropArea :TCropArea;
+
+begin
+  if (cbBoxList.ItemIndex>-1) then
+  begin
+    CropArea :=TCropArea(cbBoxList.Items.Objects[cbBoxList.ItemIndex]);
+    if CropArea<>nil
+    then CropArea.FlipHRight;
+  end;
+end;
+
+procedure TFormBGRAImageManipulationDemo.btCFlipVUpClick(Sender: TObject);
+var
+   CropArea :TCropArea;
+
+begin
+  if (cbBoxList.ItemIndex>-1) then
+  begin
+    CropArea :=TCropArea(cbBoxList.Items.Objects[cbBoxList.ItemIndex]);
+    if CropArea<>nil
+    then CropArea.FlipVUp;
+  end;
+end;
+
+procedure TFormBGRAImageManipulationDemo.btCRotateRightClick(Sender: TObject);
+var
+   CropArea :TCropArea;
+
+begin
+  if (cbBoxList.ItemIndex>-1) then
+  begin
+    CropArea :=TCropArea(cbBoxList.Items.Objects[cbBoxList.ItemIndex]);
+    if CropArea<>nil
+    then CropArea.RotateRight;
+  end;
+end;
+
 procedure TFormBGRAImageManipulationDemo.btnLoadCropListClick(Sender: TObject);
 begin
   try