fxGR32.pas 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. unit fxGR32;
  2. interface
  3. uses
  4. System.SysUtils,
  5. System.Types,
  6. System.UITypes,
  7. System.Classes,
  8. System.Variants,
  9. FMX.Types,
  10. FMX.Controls,
  11. FMX.Forms,
  12. FMX.Graphics,
  13. FMX.Dialogs,
  14. FMX.Objects,
  15. FMX.Controls.Presentation,
  16. FMX.StdCtrls,
  17. System.Math.Vectors,
  18. GR32_Transforms,
  19. GR32, System.Math,
  20. FMX.Layouts,
  21. TypInfo,
  22. FMX.Platform,
  23. FMX.ListBox,
  24. GR32_Resamplers;
  25. type
  26. TfxFMXGR32 = class(TForm)
  27. Image1: TImage;
  28. Layout2: TLayout;
  29. Image2: TImage;
  30. Rectangle3: TRectangle;
  31. Label13: TLabel;
  32. Rectangle1: TRectangle;
  33. Label1: TLabel;
  34. CmbResamplerClassNames: TComboBox;
  35. procedure Button1Click(Sender: TObject);
  36. procedure FormCreate(Sender: TObject);
  37. procedure Layout2Resize(Sender: TObject);
  38. procedure CmbResamplerClassNamesChange(Sender: TObject);
  39. private const
  40. DESIRE_FORMAT: TPixelFormat =
  41. {$IFDEF RGBA_FORMAT}
  42. TPixelFormat.RGBA
  43. {$ELSE}
  44. TPixelFormat.BGRA
  45. {$ENDIF}
  46. ;
  47. private
  48. { Private declarations }
  49. Transformation: TProjectiveTransformation;
  50. FScaleFactor: Single;
  51. Vertices: array [0..3] of TPointF;
  52. procedure DoPointChanged(Sender: TObject; var X, Y: Single);
  53. procedure DoTransform;
  54. public
  55. { Public declarations }
  56. end;
  57. var
  58. fxFMXGR32: TfxFMXGR32;
  59. implementation
  60. {$R *.fmx}
  61. procedure TfxFMXGR32.Button1Click(Sender: TObject);
  62. //var
  63. // M: TMatrix;
  64. begin
  65. // M.m11 := 0.945039331912994;
  66. // m.m21 := 0;
  67. // m.m31 := -0.000584687339141965;
  68. // m.m12 := 0;
  69. // m.m22 := 0.535142779350281;
  70. // m.m32 := -0.00280034448951483;
  71. // m.m13 := 0;
  72. // m.m23 := 0;
  73. // m.m33 := 1;
  74. //
  75. //
  76. // PaintBox1.Canvas.BeginScene();
  77. // paintBox1.Canvas.MultiplyMatrix(M);
  78. // PaintBox1.Canvas.DrawBitmap(Image1.Bitmap, RectF(0,0,Image1.Bitmap.Width,Image1.Bitmap.Height), PaintBox1.LocalRect, 1);
  79. // paintBox1.Canvas.EndScene;
  80. DoTransform;
  81. end;
  82. procedure TfxFMXGR32.CmbResamplerClassNamesChange(Sender: TObject);
  83. begin
  84. DoTransform;
  85. end;
  86. procedure TfxFMXGR32.DoPointChanged(Sender: TObject; var X, Y: Single);
  87. var
  88. idx: Integer;
  89. begin
  90. idx := (Sender as TComponent).Tag;
  91. Vertices[idx].X := X;
  92. Vertices[idx].Y := Y;
  93. DoTransform;
  94. end;
  95. procedure TfxFMXGR32.DoTransform;
  96. var
  97. src, dst: TBitmap32;
  98. maxx,maxy: Single;
  99. I: Integer;
  100. s: string;
  101. dstBitmap, tmp: TBitmap;
  102. begin
  103. if image1.Bitmap.PixelFormat <> DESIRE_FORMAT then
  104. begin
  105. s := TypInfo.GetEnumName(TypeInfo(TPixelFormat), Integer(image1.Bitmap.PixelFormat));
  106. ShowMessage('wrong with ' + s);
  107. Exit;
  108. end;
  109. maxx := 0;
  110. maxy := 0;
  111. for I := 0 to 3 do
  112. begin
  113. maxx := max(maxx, Vertices[I].X);
  114. maxy := max(maxy, Vertices[I].Y);
  115. end;
  116. Transformation.X0 := Vertices[0].X;
  117. Transformation.Y0 := Vertices[0].Y;
  118. Transformation.X1 := Vertices[1].X;
  119. Transformation.Y1 := Vertices[1].Y;
  120. Transformation.X2 := Vertices[2].X;
  121. Transformation.Y2 := Vertices[2].Y;
  122. Transformation.X3 := Vertices[3].X;
  123. Transformation.Y3 := Vertices[3].Y;
  124. Transformation.SrcRect := FloatRect(0,0,200,200);
  125. src := TBitmap32.Create();
  126. dst := TBitmap32.Create();
  127. dstBitmap := TBitmap.Create;
  128. try
  129. src.Assign(Image1.Bitmap);
  130. with CmbResamplerClassNames do
  131. if ItemIndex >= 0 then
  132. Src.ResamplerClassName := Items[ ItemIndex ];
  133. dst.SetSize(ceil(maxx), ceil(maxy));
  134. Dst.Clear($00000000);
  135. Transform(Dst, Src, Transformation);
  136. dstBitmap.Assign(dst);
  137. if FScaleFactor = 1 then
  138. Image2.Bitmap := dstBitmap
  139. else
  140. begin
  141. tmp := TBitmap.Create;
  142. try
  143. tmp.SetSize(Round(dstBitmap.Width * FScaleFactor), Round(dstBitmap.Height * FScaleFactor));
  144. tmp.Canvas.BeginScene;
  145. tmp.Clear(0);
  146. tmp.Canvas.DrawBitmap(dstBitmap, dstBitmap.Bounds, tmp.Bounds, 1);
  147. tmp.Canvas.EndScene;
  148. Image2.Bitmap := tmp;
  149. finally
  150. tmp.Free;
  151. end;
  152. end;
  153. finally
  154. dstBitmap.Free;
  155. dst.Free;
  156. src.Free;
  157. end;
  158. end;
  159. procedure TfxFMXGR32.FormCreate(Sender: TObject);
  160. var
  161. I: Integer;
  162. Shape: TSelectionPoint;
  163. ScreenSrv: IFMXScreenService;
  164. begin
  165. if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, ScreenSrv) then
  166. FScaleFactor := ScreenSrv.GetScreenScale
  167. else
  168. FScaleFactor := 1;
  169. Transformation := TProjectiveTransformation.Create;
  170. Vertices[0] := Point(-10,-20);
  171. Vertices[1] := Point(200,0);
  172. Vertices[2] := Point(200,200);
  173. Vertices[3] := Point(0,200);
  174. // Vertices[0] := Point(18,49);
  175. // Vertices[1] := Point(265,6);
  176. // Vertices[2] := Point(292,196);
  177. // Vertices[3] := Point(58,239);
  178. for I := 0 to 3 do
  179. begin
  180. Shape := TSelectionPoint.Create(Self);
  181. Shape.Parent := Image2;
  182. Shape.GripSize := 9;
  183. Shape.Position.X := Vertices[i].X;
  184. Shape.Position.Y := Vertices[i].Y;
  185. Shape.OnTrack := DoPointChanged;
  186. Shape.Tag := i;
  187. end;
  188. ResamplerList.GetClassNames(CmbResamplerClassNames.Items);
  189. CmbResamplerClassNames.ItemIndex := 0;
  190. end;
  191. procedure TfxFMXGR32.Layout2Resize(Sender: TObject);
  192. begin
  193. Image1.Position.Point := TPoint.Zero;
  194. if Layout2.Width > Layout2.Height then
  195. begin
  196. Image1.Size.Size := TSizeF.Create(Layout2.Width / 2, Layout2.Height);
  197. Image2.Position.Point := PointF(Layout2.Width/2, 0);
  198. Image2.Size.Size := TSizeF.Create(Layout2.Width / 2, Layout2.Height);
  199. end
  200. else
  201. begin
  202. Image1.Size.Size := TSizeF.Create(Layout2.Width, Layout2.Height/2);
  203. Image2.Position.Point := PointF(0, Layout2.Height/2);
  204. Image2.Size.Size := TSizeF.Create(Layout2.Width, Layout2.Height/2);
  205. end;
  206. end;
  207. end.