| 
					
				 | 
			
			
				@@ -1,6 +1,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 unit ksBitmapHelper;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 非安卓部分拷贝自 FlyUtils.TBitmapHelper
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 部分拷贝自 FlyUtils.TBitmapHelper
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$DEFINE FMX}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -74,6 +74,9 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// 用于在线程中代替 LoadThumbnailFromFile ,不用自己调用 Synchronize 了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// <remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// UseEmbedded 只有Windows下可用,而且缩略图大小不可控
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// </remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     procedure SyncLoadThumbnailFromFile(const AFileName: string; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const UseEmbedded: Boolean = True);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// <summary>
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -83,8 +86,13 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// 用于在线程中代替 LoadThumbnailFromStream ,不用自己调用 Synchronize 了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    procedure SyncLoadThumbnailFromStream(Stream: TStream; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const UseEmbedded: Boolean = True; const AutoCut: Boolean = True);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// <remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// UseEmbedded 只有Windows下可用,而且缩略图大小不可控
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// </remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    procedure SyncLoadThumbnailFromStream(const Stream: TStream; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const UseEmbedded: Boolean = True; const AutoCut: Boolean = True); overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function SyncLoadThumbnailFromStream(const AStream: TStream; const ASrc, ADest: TRectF;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const UseEmbedded: Boolean): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// 用于在线程中代替 Assign ,不用自己调用 Synchronize 了。
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// </summary>
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -102,8 +110,16 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class function GetImageSize(const AStream: TStream): TPointF; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class function LoadFromStream(const AStream: TStream; const Bitmap: TBitmapSurface;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const MaxSizeLimit: Cardinal = 0): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// <remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// UseEmbedded 只有Windows下可用,而且缩略图大小不可控
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// </remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class function LoadThumbnailFromStream(const AStream: TStream; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const UseEmbedded: Boolean; const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const UseEmbedded: Boolean; const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// <remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// UseEmbedded 只有Windows下可用,而且缩略图大小不可控
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// </remarks>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    class function LoadThumbnailFromStream(const AStream: TStream; const ASrc, ADest: TRectF;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const UseEmbedded: Boolean; const Bitmap: TBitmapSurface): Boolean; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -235,7 +251,9 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function LoadFromStream(const AStream: TStream; const Bitmap: TBitmapSurface;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const MaxSizeLimit: Cardinal): Boolean; override;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function LoadThumbnailFromStream(const AStream: TStream; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const UseEmbedded: Boolean; const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      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;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$IFDEF MSWINDOWS}
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -246,7 +264,9 @@ type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   public
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class function GetImageSize(const AStream: TStream): TPointF; overload;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function LoadThumbnailFromStream(const AStream: TStream; const AFitWidth, AFitHeight: Single;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const UseEmbedded: Boolean; const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      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;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   {$ENDIF}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {$ENDIF}
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -909,7 +929,57 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-procedure TKngStrBitmapHelper.SyncLoadThumbnailFromStream(Stream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TKngStrBitmapHelper.SyncLoadThumbnailFromStream(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const ASrc, ADest: TRectF; const UseEmbedded: Boolean): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  S: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Surf: TBitmapSurface;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if AStream.Position > 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // need to create temp stream
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    S := TMemoryStream.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      S.CopyFrom(AStream, AStream.Size - AStream.Position);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      S.Position := 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Surf := TBitmapSurface.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if TBitmapCodecManager.LoadThumbnailFromStream(S, ASrc, ADest, UseEmbedded, Surf) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TThread.Synchronize(nil,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            procedure
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              Assign(Surf);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          raise EBitmapLoadingFailed.Create(SThumbnailLoadingFailed);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Surf.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      S.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if AStream.Size = 0 then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Clear(0)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Surf := TBitmapSurface.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if TBitmapCodecManager.LoadThumbnailFromStream(AStream, ASrc, ADest, UseEmbedded, Surf) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TThread.Synchronize(nil,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            procedure
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              Assign(Surf);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          raise EBitmapLoadingFailed.Create(SThumbnailLoadingFailed);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Surf.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+procedure TKngStrBitmapHelper.SyncLoadThumbnailFromStream(const Stream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AFitWidth, AFitHeight: Single; const UseEmbedded: Boolean; const AutoCut: Boolean);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   S: TStream;
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1023,6 +1093,32 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class function TKngStrBitmapCodecManager.LoadThumbnailFromStream(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const AStream: TStream; const ASrc, ADest: TRectF; const UseEmbedded: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CodecClass: TCustomBitmapCodecClass;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Codec: TCustomBitmapCodec;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DataType: String;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DataType := TImageTypeChecker.GetType(AStream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CodecClass := GuessCodecClass(DataType, TBitmapCodecDescriptorField.Extension);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if CodecClass <> nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Codec := CodecClass.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$IFDEF ANDROID}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := TBitmapCodecAndroid(Codec).LoadThumbnailFromStream(AStream, ASrc, ADest, UseEmbedded, Bitmap);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      {$ELSE}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Result := TBitmapCodecWIC(Codec).LoadThumbnailFromStream(AStream, ASrc, ADest, UseEmbedded, 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;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1314,6 +1410,72 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function TBitmapCodecAndroid.LoadThumbnailFromStream(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const ASrc, ADest: TRectF; const UseEmbedded: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempStream: TMemoryStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TempArray: TJavaArray<Byte>;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NativeBitmap1, NativeBitmap2: JBitmap;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  LoadOptions: JBitmapFactory_Options;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SavePosition: Int64;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if IsGIFStream(AStream) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Result := LoadMovieFromStreamScaled(AStream, Bitmap, TPoint.Create(Round(ADest.Width), Round(ADest.Height)))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    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;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //kngstr
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if NativeBitmap1 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (LoadOptions.outWidth < 1) or (LoadOptions.outHeight < 1) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 剪裁
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (not ASrc.IsEmpty) and (ASrc.Width < LoadOptions.outWidth) and (ASrc.Height < LoadOptions.outHeight) then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          NativeBitmap2 := TJBitmap.JavaClass.createBitmap(NativeBitmap1, Round(ASrc.Left), Round(ASrc.Top), Round(ASrc.Width), Round(ASrc.Height));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //kngstr
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if NativeBitmap2 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          NativeBitmap1.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          NativeBitmap1 := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          NativeBitmap1 := NativeBitmap2;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //缩放
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        NativeBitmap2 := TJBitmap.JavaClass.createScaledBitmap(NativeBitmap1, Round(ADest.Width), Round(ADest.Height), True);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //kngstr
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if NativeBitmap2 = nil then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Exit(False);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := JBitmapToSurface(NativeBitmap2, Bitmap)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          NativeBitmap2.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        NativeBitmap1.recycle;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AStream.Position := SavePosition;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TBitmapCodecAndroid.LoadThumbnailFromStream(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AFitWidth, AFitHeight: Single; const UseEmbedded: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AutoCut: Boolean; const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1532,6 +1694,89 @@ begin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function TBitmapCodecWIC.LoadThumbnailFromStream(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const ASrc, ADest: TRectF; const UseEmbedded: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Decoder: IWICBitmapDecoder;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CopyStream: TMemoryStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Stream: IWICStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Frame: IWICBitmapFrameDecode;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Bmp: IWICBitmapSource;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Converter: IWICFormatConverter;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Scaler: IWICBitmapScaler;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Clipper: IWICBitmapClipper;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Width, Height: UINT;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WRect: WICRect;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  LResult: HRESULT;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Result := False;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CopyStream := TMemoryStream.Create;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    CopyStream.CopyFrom(AStream, AStream.Size);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ImagingFactory.CreateStream(Stream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Stream.InitializeFromMemory(CopyStream.Memory, CopyStream.Size);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //kngstr
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ImagingFactory.CreateDecoderFromStream(Stream, GUID_NULL, WICDecodeMetadataCacheOnDemand, Decoder);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if Decoder <> nil then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Decoder.GetFrame(0, Frame);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if UseEmbedded then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Frame.GetThumbnail(Bmp);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if Bmp <> nil then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ImagingFactory.CreateFormatConverter(Converter);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if Succeeded(Converter.Initialize(Bmp, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, 0)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Converter.GetSize(Width, Height);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Bitmap.SetSize(Width, Height, TPixelFormat.BGRA);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Result := Succeeded(Converter.CopyPixels(nil, Bitmap.Pitch, Height * Cardinal(Bitmap.Pitch),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PByte(Bitmap.Bits)));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else if Frame <> nil then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Frame.GetSize(Width, Height);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Clipper := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (not ASrc.IsEmpty) and (ASrc.Width < Width) and (ASrc.Height < Height) then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WRect.X := Trunc(ASrc.Left);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WRect.Y := Trunc(ASrc.Top);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WRect.Width := Trunc(ASrc.Width);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WRect.Height := Trunc(ASrc.Height);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // 剪裁
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ImagingFactory.CreateBitmapClipper(Clipper);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if not Succeeded(Clipper.Initialize(frame, WRect)) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Clipper := nil;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LResult := S_FALSE;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 缩放
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ImagingFactory.CreateBitmapScaler(Scaler);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Clipper <> nil) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          LResult := Scaler.Initialize(Clipper, Trunc(ADest.Width), Trunc(ADest.Height), WICBitmapInterpolationModeLinear);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if not Succeeded(LResult) then
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          LResult := Scaler.Initialize(Frame, Trunc(ADest.Width), Trunc(ADest.Height), WICBitmapInterpolationModeLinear);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if Succeeded(LResult) then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ImagingFactory.CreateFormatConverter(Converter);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if Succeeded(Converter.Initialize(scaler, GUID_WICPixelFormat32bppPBGRA,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            WICBitmapDitherTypeNone, nil, 0, 0)) then begin
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Converter.GetSize(Width, Height);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Bitmap.SetSize(Width, Height, TPixelFormat.BGRA);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Result := Succeeded(Converter.CopyPixels(nil, Bitmap.Pitch, Height * Cardinal(Bitmap.Pitch),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              PByte(Bitmap.Bits)));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    CopyStream.Free;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+end;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function TBitmapCodecWIC.LoadThumbnailFromStream(const AStream: TStream;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const AFitWidth, AFitHeight: Single; const UseEmbedded, AutoCut: Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const Bitmap: TBitmapSurface): Boolean;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var
 
			 |