| 
					
				 | 
			
			
				@@ -6,6 +6,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 interface
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{$SCOPEDENUMS ON}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uses
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$IFDEF FMX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   FMX.Graphics,
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -97,6 +99,7 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// 用于在线程中代替 Assign ,不用自己调用 Synchronize 了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     procedure SyncAssign(Source: TPersistent);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    procedure SaveToStream(Stream: TStream; const Extension: string; SaveParams: PBitmapCodecSaveParams = nil); overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -120,6 +123,8 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// </remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class function LoadThumbnailFromStream(const AStream: TStream; const ASrc, ADest: TRectF;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const UseEmbedded: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    class function Rotate(const Extension: string; const Angle: Single; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    class function Rotate(const AStream: TStream; const Angle: Single): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -177,9 +182,10 @@ uses 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Androidapi.Helpers,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   FMX.Helpers.Android,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Androidapi.JNI.GraphicsContentViewText,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Androidapi.JNI.JavaTypes,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$IFDEF MSWINDOWS}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  FMX.Canvas.D2D, Winapi.Wincodec,  Winapi.Windows,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FMX.Canvas.D2D, Winapi.Wincodec, Winapi.Windows, Winapi.ActiveX,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Vcl.Consts,
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -235,6 +241,8 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$IFDEF FMX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TBitmapCodecAndroid = class(FMX.Graphics.Android.TBitmapCodecAndroid)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  private const
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DefaultSaveQuality = 75;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   private
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class function IsGIFStream(const Stream: TStream): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function LoadMovieFromStreamScaled(const AStream: TStream;
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -254,6 +262,8 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const UseEmbedded: Boolean; const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function LoadThumbnailFromStream(const AStream: TStream; const ASrc, ADest: TRectF;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const UseEmbedded: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function Rotate(const Extension: string; const Angle: Single; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function Rotate(const AStream: TStream; const Angle: Single): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$IFDEF MSWINDOWS}
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -267,6 +277,8 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const UseEmbedded: Boolean; const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function LoadThumbnailFromStream(const AStream: TStream; const ASrc, ADest: TRectF;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const UseEmbedded: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function Rotate(const Extension: string; const Angle: Single; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function Rotate(const AStream: TStream; const Angle: Single): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$ENDIF}
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -831,6 +843,26 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+procedure TKngStrBitmapHelper.SaveToStream(Stream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Extension: string; SaveParams: PBitmapCodecSaveParams);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Surf: TBitmapSurface;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TMonitor.Enter(Self);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Surf := TBitmapSurface.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Surf.Assign(Self);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not TBitmapCodecManager.SaveToStream(Stream, Surf, Extension, SaveParams) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        raise EBitmapSavingFailed.Create(SBitmapSavingFailed);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Surf.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TMonitor.Exit(Self);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$IFDEF FMX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 procedure TKngStrBitmapHelper.SyncAssign(Source: TPersistent);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 begin
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1118,6 +1150,58 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class function TKngStrBitmapCodecManager.Rotate(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Angle: Single): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CodecClass: TCustomBitmapCodecClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Codec: TCustomBitmapCodec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DataType: String;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (not Assigned(AStream)) or (AStream.Size - AStream.Position <= 0) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DataType := TImageTypeChecker.GetType(AStream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CodecClass := GuessCodecClass(DataType, TBitmapCodecDescriptorField.Extension);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if CodecClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Codec := CodecClass.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := TBitmapCodecAndroid(Codec).Rotate(AStream, Angle);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := TBitmapCodecWIC(Codec).Rotate(AStream, Angle);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Codec.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class function TKngStrBitmapCodecManager.Rotate(const Extension: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Angle: Single; const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CodecClass: TCustomBitmapCodecClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Codec: TCustomBitmapCodec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Extension = '' then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CodecClass := GuessCodecClass(Extension, TBitmapCodecDescriptorField.Extension);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if CodecClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Codec := CodecClass.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := TBitmapCodecAndroid(Codec).Rotate(Extension, Angle, Bitmap);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := TBitmapCodecWIC(Codec).Rotate(Extension, Angle, Bitmap);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Codec.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class function TKngStrBitmapCodecManager.LoadThumbnailFromStream(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AStream: TStream; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const UseEmbedded: Boolean; const AutoCut: Boolean;
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1475,6 +1559,114 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TBitmapCodecAndroid.Rotate(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Angle: Single): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NativeBitmap1, NativeBitmap2: JBitmap;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SaveFormat: JBitmap_CompressFormat;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Matrix: JMatrix;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempStream: TMemoryStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempArray: TJavaArray<Byte>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  LoadOptions: JBitmapFactory_Options;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SavePosition: Int64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  OutByteStream: JByteArrayOutputStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ContentBytes: TJavaArray<Byte>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DataType: string;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DataType := TImageTypeChecker.GetType(AStream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if DataType = SGIFImageExtension then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SavePosition := AStream.Position;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TempStream := TMemoryStream.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TempStream.CopyFrom(AStream, AStream.Size);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TempArray := TJavaArray<Byte>.Create(TempStream.Size);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Move(TempStream.Memory^, TempArray.Data^, TempStream.Size);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      TempStream.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LoadOptions := TJBitmapFactory_Options.JavaClass.init;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LoadOptions.inJustDecodeBounds := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    NativeBitmap1 := TJBitmapFactory.JavaClass.decodeByteArray(TempArray, 0, TempArray.Length, LoadOptions);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    TempArray := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if NativeBitmap1 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Matrix := TJMatrix.JavaClass.init;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Matrix.postRotate(Angle);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      NativeBitmap2 := TJBitmap.JavaClass.createBitmap(NativeBitmap1, 0, 0, NativeBitmap1.getWidth, NativeBitmap1.getHeight, Matrix, True);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      NativeBitmap1.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if NativeBitmap2 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if SameText(DataType, SPNGImageExtension) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SaveFormat := TJBitmap_CompressFormat.JavaClass.PNG
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SaveFormat := TJBitmap_CompressFormat.JavaClass.JPEG;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      OutByteStream := TJByteArrayOutputStream.JavaClass.init(0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := NativeBitmap2.compress(SaveFormat, 100, OutByteStream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      NativeBitmap2.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Result and (OutByteStream.size > 0) then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ContentBytes := OutByteStream.toByteArray;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AStream.Size := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AStream.WriteBuffer(ContentBytes.Data^, OutByteStream.size);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := Result and (OutByteStream.size > 0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AStream.Position := SavePosition;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TBitmapCodecAndroid.Rotate(const Extension: string; const Angle: Single; const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NativeBitmap1, NativeBitmap2: JBitmap;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SaveFormat: JBitmap_CompressFormat;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Matrix: JMatrix;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SaveQuality: Integer;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if Extension = SGIFImageExtension then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NativeBitmap1 := TJBitmap.JavaClass.createBitmap(Bitmap.Width, Bitmap.Height, TJBitmap_Config.JavaClass.ARGB_8888);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if NativeBitmap1 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := SurfaceToJBitmap(Bitmap, NativeBitmap1);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if not Result then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Exit;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Matrix := TJMatrix.JavaClass.init;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Matrix.postRotate(Angle);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    NativeBitmap2 := TJBitmap.JavaClass.createBitmap(NativeBitmap1, 0, 0, Bitmap.Width, Bitmap.Height, Matrix, True);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    NativeBitmap1.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if NativeBitmap2 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := JBitmapToSurface(NativeBitmap2, Bitmap);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    NativeBitmap2.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function TBitmapCodecAndroid.LoadThumbnailFromStream(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AFitWidth, AFitHeight: Single; const UseEmbedded: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean;
 
			 |