Browse Source

Assign sprite to and from animated Gif

Johann ELSASS 5 years ago
parent
commit
eaabaf00d8
1 changed files with 68 additions and 20 deletions
  1. 68 20
      bgraspriteanimation.pas

+ 68 - 20
bgraspriteanimation.pas

@@ -26,6 +26,19 @@ uses
   BCBaseCtrls, BGRABitmap, BGRABitmapTypes, BCTypes, BGRAAnimatedGif;
   BCBaseCtrls, BGRABitmap, BGRABitmapTypes, BCTypes, BGRAAnimatedGif;
 
 
 type
 type
+  TBGRASpriteAnimation = class;
+
+  { TSpriteBitmap }
+
+  TSpriteBitmap = class(TBitmap)
+  private
+    FOwner: TBGRASpriteAnimation;
+  protected
+    procedure AssignTo(Dest: TPersistent); override;
+  public
+    constructor Create(AOwner: TBGRASpriteAnimation); overload;
+    procedure Assign(Source: TPersistent); override;
+  end;
 
 
   TFlipMode = (flNone, flHorizontal, flVertical, flBoth);
   TFlipMode = (flNone, flHorizontal, flVertical, flBoth);
   TRotationMode = (rtNone, rtClockWise, rtCounterClockWise, rt180);
   TRotationMode = (rtNone, rtClockWise, rtCounterClockWise, rt180);
@@ -96,6 +109,7 @@ type
   public
   public
     { Public declarations }
     { Public declarations }
     procedure GifImageToSprite(Gif: TBGRAAnimatedGif);
     procedure GifImageToSprite(Gif: TBGRAAnimatedGif);
+    procedure SpriteToGifImage(Gif: TBGRAAnimatedGif);
     procedure LoadFromResourceName(Instance: THandle; const ResName: string); overload;
     procedure LoadFromResourceName(Instance: THandle; const ResName: string); overload;
     procedure LoadFromBitmapResource(const Resource: string); overload;
     procedure LoadFromBitmapResource(const Resource: string); overload;
     procedure LoadFromBitmapStream(AStream: TStream);
     procedure LoadFromBitmapStream(AStream: TStream);
@@ -162,6 +176,30 @@ begin
   //{$I icons\bgraspriteanimation_icon.lrs}
   //{$I icons\bgraspriteanimation_icon.lrs}
   RegisterComponents('BGRA Controls', [TBGRASpriteAnimation]);
   RegisterComponents('BGRA Controls', [TBGRASpriteAnimation]);
 end;
 end;
+
+{ TSpriteBitmap }
+
+procedure TSpriteBitmap.AssignTo(Dest: TPersistent);
+begin
+  if Dest is TBGRAAnimatedGif then
+    FOwner.SpriteToGifImage(TBGRAAnimatedGif(Dest));
+  inherited AssignTo(Dest);
+end;
+
+constructor TSpriteBitmap.Create(AOwner: TBGRASpriteAnimation);
+begin
+  inherited Create;
+  FOwner := AOwner;
+end;
+
+procedure TSpriteBitmap.Assign(Source: TPersistent);
+begin
+  if Source is TBGRAAnimatedGif then
+    FOwner.GifImageToSprite(TBGRAAnimatedGif(Source))
+  else
+    inherited Assign(Source);
+end;
+
 {$ENDIF}
 {$ENDIF}
 
 
 { TBGRASpriteAnimation }
 { TBGRASpriteAnimation }
@@ -521,10 +559,10 @@ begin
   if SpriteRotation in [rtClockWise,rtCounterClockWise] then
   if SpriteRotation in [rtClockWise,rtCounterClockWise] then
   begin
   begin
     PreferredWidth := Sprite.Height;
     PreferredWidth := Sprite.Height;
-    PreferredHeight := Sprite.Width;
+    PreferredHeight := Sprite.Width div SpriteCount;
   end else
   end else
   begin
   begin
-    PreferredWidth := Sprite.Width;
+    PreferredWidth := Sprite.Width div SpriteCount;
     PreferredHeight := Sprite.Height;
     PreferredHeight := Sprite.Height;
   end;
   end;
 end;
 end;
@@ -546,6 +584,32 @@ begin
   AnimSpeed := Gif.TotalAnimationTimeMs div Gif.Count;
   AnimSpeed := Gif.TotalAnimationTimeMs div Gif.Count;
 end;
 end;
 
 
+procedure TBGRASpriteAnimation.SpriteToGifImage(Gif: TBGRAAnimatedGif);
+var
+  i: integer;
+  TempSpriteWidth: Integer;
+  TempSpritePosition: Integer;
+  TempSpriteBGRA, TempSprite: TBGRABitmap;
+begin
+  gif.Clear;
+  if AnimRepeat > high(Word) then
+    gif.LoopCount := 0
+  else
+    gif.LoopCount := AnimRepeat;
+  TempSpriteBGRA := TBGRABitmap.Create(FSprite);
+  TempSpriteWidth := TempSpriteBGRA.Width div FSpriteCount;
+  gif.SetSize(TempSpriteWidth, TempSpriteBGRA.Height);
+  for i:=0 to FSpriteCount-1 do
+  begin
+    TempSpritePosition := -TempSpriteWidth * i;
+    TempSprite := TBGRABitmap.Create(TempSpriteWidth, TempSpriteBGRA.Height);
+    TempSprite.BlendImage(TempSpritePosition, 0, TempSpriteBGRA, boLinearBlend);
+    gif.AddFullFrame(TempSprite, FAnimSpeed);
+    TempSprite.Free;
+  end;
+  TempSpriteBGRA.Free;
+end;
+
 procedure TBGRASpriteAnimation.LoadFromResourceName(Instance: THandle;
 procedure TBGRASpriteAnimation.LoadFromResourceName(Instance: THandle;
   const ResName: string);
   const ResName: string);
 var
 var
@@ -605,26 +669,10 @@ end;
 
 
 procedure TBGRASpriteAnimation.SpriteToAnimatedGif(Filename: string);
 procedure TBGRASpriteAnimation.SpriteToAnimatedGif(Filename: string);
 var
 var
-  i: integer;
   gif : TBGRAAnimatedGif;
   gif : TBGRAAnimatedGif;
-  TempSpriteWidth: Integer;
-  TempSpritePosition: Integer;
-  TempSpriteBGRA, TempSprite: TBGRABitmap;
 begin
 begin
   gif := TBGRAAnimatedGif.Create;
   gif := TBGRAAnimatedGif.Create;
-  gif.LoopCount := High(Word);
-  TempSpriteBGRA := TBGRABitmap.Create(FSprite);
-  TempSpriteWidth := TempSpriteBGRA.Width div FSpriteCount;
-  gif.SetSize(TempSpriteWidth, TempSpriteBGRA.Height);
-  for i:=0 to FSpriteCount-1 do
-  begin
-    TempSpritePosition := -TempSpriteWidth * i;
-    TempSprite := TBGRABitmap.Create(TempSpriteWidth, TempSpriteBGRA.Height);
-    TempSprite.BlendImage(TempSpritePosition, 0, TempSpriteBGRA, boLinearBlend);
-    gif.AddFullFrame(TempSprite, FAnimSpeed);
-    TempSprite.Free;
-  end;
-  TempSpriteBGRA.Free;
+  SpriteToGifImage(Gif);
   gif.SaveToFile(Filename);
   gif.SaveToFile(Filename);
   gif.Free;
   gif.Free;
 end;
 end;
@@ -709,7 +757,7 @@ begin
   FCenter := True;
   FCenter := True;
   FProportional := True;
   FProportional := True;
   FStretch := True;
   FStretch := True;
-  FSprite := TBitmap.Create;
+  FSprite := TSpriteBitmap.Create(self);
   FSprite.OnChange:=SpriteChange;
   FSprite.OnChange:=SpriteChange;
   FSpriteCount := 1;
   FSpriteCount := 1;
   FSpriteFillOpacity := 255;
   FSpriteFillOpacity := 255;