#1
Posted
:
Thursday, January 24, 2019 4:53:53 PM(UTC)
Groups: Registered, Tech Support, Administrators
Posts: 199
Was thanked: 28 time(s) in 28 post(s)
Animated GIFs can reduce the size of the file in a number of ways. One key method is limiting the amount of information stored in each frame to only what has changed. This could be providing a small rectangle for a change, or using transparency to overlay the new frame on the previous. Loading in one of these files with our SDK will load precisely what is stored in each frame, even if that's just a small rectangle. The downside to this of course, is when attempting to view a particular frame of the animation, it could rely on combining any number of previous frames together. The
RasterImageAnimator is designed specifically to handle this process for you.
Below is a function which will extract each frame of an animation using this class. It also contains a faster method for extracting the pages when animation is not required (such as the pages of a PDF or TIF). I've also attached a complete sample project which demonstrates this function.
Code:
static void ExtractFrames(string inputFile, string outputDir)
{
// Ensure the output directory exists
Directory.CreateDirectory(outputDir);
// Load the original image
using (var codecs = new RasterCodecs())
{
codecs.Options.Load.AllPages = true;
using (var animatedImage = codecs.Load(inputFile))
{
// Check if the image isn't animated
if (animatedImage.AnimationGlobalLoop < -1)
{
// Extract each frame/page directly
for (int page = 1; page <= animatedImage.PageCount; page++)
{
animatedImage.Page = page; // Specifies the page to be saved
codecs.Save(
animatedImage,
Path.Combine(outputDir, $"{page}.png"),
RasterImageFormat.Png,
0
);
}
}
else
{
// Use a RasterImageAnimator to extract each frame
// Refer to: https://www.leadtools.com/help/leadtools/v20/dh/l/rasterimageanimator.html
// Create a target image for drawing the animation onto
using (RasterImage targetImage = new RasterImage(
RasterMemoryFlags.Conventional, // Create in RAM
animatedImage.AnimationGlobalSize.Width, // Need to allocated enough
animatedImage.AnimationGlobalSize.Height, // space for all image data
animatedImage.BitsPerPixel, // Ensure the image properties
animatedImage.Order, // match exactly
animatedImage.ViewPerspective,
null,
IntPtr.Zero,
0
))
{
// Ensure the palette matches
animatedImage.CopyPaletteTo(targetImage);
// Only need to loop once for frame extraction
animatedImage.AnimationGlobalLoop = 1;
// Remove any delays from the animation
int page;
for (page = 1; page <= animatedImage.PageCount; page++)
{
animatedImage.Page = page;
animatedImage.AnimationDelay = 0; // 0ms delay between frames
animatedImage.AnimationWaitUserInput = false; // No user input required
}
// Perform the frame extraction
page = 1;
RasterImageAnimatorState state;
using (var animator = new RasterImageAnimator(targetImage, animatedImage))
do
{
// Animate
state = animator.Process();
// Save out the current frame once rendered
if (state == RasterImageAnimatorState.PostRender)
codecs.Save(
targetImage,
Path.Combine(outputDir, $"{page++}.png"),
RasterImageFormat.Png,
0
);
}
while (state != RasterImageAnimatorState.End);
}
}
}
}
}
Thanks,
Anthony Northrup
Developer Support Engineer
LEAD Technologies, Inc.
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.