Comments (5)
I toyed around with the implementation below, using a dispatch group, it worked really well up until I hit the problem of collecting the frames in-order. I tried using NSMutableArray's insertObject:atIndex:, but it has some really weird behavior when you insert out of order (which I think would be necessary for multi-threaded operation).
+ (id)imageWithData:(NSData *)data
{
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)(data), NULL);
if (!imageSource) {
return nil;
}
NSUInteger numberOfFrames = CGImageSourceGetCount(imageSource);
if (!UTTypeConformsTo(CGImageSourceGetType(imageSource), kUTTypeGIF) || numberOfFrames == 1) {
CFRelease(imageSource);
return [UIImage imageWithData:data];
}
NSDictionary *imageProperties = CFBridgingRelease(CGImageSourceCopyProperties(imageSource, NULL));
NSDictionary *GIFProperties = [imageProperties objectForKey:(NSString *)kCGImagePropertyGIFDictionary];
OLImage *animatedImage = [[OLImage alloc] init];
animatedImage.images = [NSMutableArray arrayWithCapacity:numberOfFrames];
animatedImage.frameDurations = (NSTimeInterval *) malloc(numberOfFrames * sizeof(NSTimeInterval));
animatedImage.totalDuration = 0.0f;
animatedImage.loopCount = [GIFProperties[(NSString *)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
dispatch_group_t dispatch_group = dispatch_group_create();
for (NSUInteger i = 0; i < numberOfFrames; ++i)
dispatch_group_async(dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Implement as Browsers do, to ensure UX.
//See: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser-compatibility
//See also: http://blogs.msdn.com/b/ieinternals/archive/2010/06/08/animated-gifs-slow-down-to-under-20-frames-per-second.aspx
double proposedFrameDuration = CGImageSourceGetGifFrameDelay(imageSource, i);
#ifndef OLExactGIFRepresentation
proposedFrameDuration = (proposedFrameDuration >= 0.02) ? proposedFrameDuration : 0.10f;
#endif
animatedImage.frameDurations[i] = proposedFrameDuration;
CGImageRef theImage = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
[animatedImage.images insertObject:[UIImage imageWithCGImage:theImage] atIndex:i];
CFRelease(theImage);
animatedImage.totalDuration += animatedImage.frameDurations[i];
});
dispatch_group_wait(dispatch_group, DISPATCH_TIME_FOREVER);
CFRelease(imageSource);
return animatedImage;
}
Using just addObject: (and not caring about frame ordering), I was seeing about a 10% speedup, but it varied quite a bit. I suspect that the amount of work per dispatch is low enough that the overhead eats into the gains. A better solution might be to dispatch a certain percentage of frames instead (but that still leaves the ordering problem).
from olimageview.
So I've fixed the weirdness with insertObject:atIndex: by sticking a null in its place and removing it later. But this solution is slower that the single-threaded one. :(
+ (id)imageWithData:(NSData *)data
{
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)(data), NULL);
if (!imageSource) {
return nil;
}
NSUInteger numberOfFrames = CGImageSourceGetCount(imageSource);
if (!UTTypeConformsTo(CGImageSourceGetType(imageSource), kUTTypeGIF) || numberOfFrames == 1) {
CFRelease(imageSource);
return [UIImage imageWithData:data];
}
NSDictionary *imageProperties = CFBridgingRelease(CGImageSourceCopyProperties(imageSource, NULL));
NSDictionary *GIFProperties = [imageProperties objectForKey:(NSString *)kCGImagePropertyGIFDictionary];
OLImage *animatedImage = [[OLImage alloc] init];
animatedImage.images = [NSMutableArray arrayWithCapacity:numberOfFrames];
animatedImage.frameDurations = (NSTimeInterval *) malloc(numberOfFrames * sizeof(NSTimeInterval));
animatedImage.totalDuration = 0.0f;
animatedImage.loopCount = [GIFProperties[(NSString *)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
dispatch_group_t dispatch_group = dispatch_group_create();
for (NSUInteger i = 0; i < numberOfFrames; ++i)
[animatedImage.images addObject:[NSNull null]];
for (NSUInteger i = 0; i < numberOfFrames; ++i)
dispatch_group_async(dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Implement as Browsers do, to ensure UX.
//See: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser-compatibility
//See also: http://blogs.msdn.com/b/ieinternals/archive/2010/06/08/animated-gifs-slow-down-to-under-20-frames-per-second.aspx
double proposedFrameDuration = CGImageSourceGetGifFrameDelay(imageSource, i);
#ifndef OLExactGIFRepresentation
proposedFrameDuration = (proposedFrameDuration >= 0.02) ? proposedFrameDuration : 0.10f;
#endif
animatedImage.frameDurations[i] = proposedFrameDuration;
CGImageRef theImage = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
[animatedImage.images replaceObjectAtIndex:i withObject:[UIImage imageWithCGImage:theImage]];
CFRelease(theImage);
animatedImage.totalDuration += animatedImage.frameDurations[i];
});
dispatch_group_wait(dispatch_group, DISPATCH_TIME_FOREVER);
CFRelease(imageSource);
return animatedImage;
}
from olimageview.
Hey Michael,
Awesome that you took a look at this but is a hard for me to identify your improvements if you post your changes here.
Can you create a fork a commit the changes there so it's easier for me to read it and help you on it
And also it will be easier to merge the changes after 👍
from olimageview.
Hey Diego,
You can check out the changes on my fork, in the "multithreaded" branch: https://github.com/koudelka/OLImageView/commits/multithreaded
I didn't submit a pull request as it looks like my solution is actually slower than the singlethread solution. The dispatch overhead seems to be greater than the savings of having multiple threads decode the frames. :(
from olimageview.
Since multithreading seems slower than the current solution, i'm closing this for now.
Would be nice to reevaluate in the future
from olimageview.
Related Issues (20)
- GIFs freeze while scrolling HOT 1
- Include improved AFNetworking category on the CocoaPod
- When use OLImageView in AVAssetExportSession as animationTool, gif animation is slow HOT 2
- Is OLImage released? HOT 3
- Does Not Build For iPhone 5S HOT 2
- A bug after dealloc OLImageView and solution HOT 1
- Release 1.2.1 HOT 1
- Large Gifs and iOS crashing HOT 5
- Zooming causes image to pause HOT 1
- iOS7 the memory problem HOT 3
- Possibly a memory leak HOT 1
- Memory issues with caching frames HOT 2
- When working with AFNetworking, there will be a retain cycle. HOT 1
- OLImageView/OLImage.m:117:49: Property 'nativeScale' not found on object of type 'UIScreen *' HOT 3
- Ops! I got o roadblock when I try to mix the olimageview.layer with a video
- Image rendered too large HOT 1
- [OLImageSourceArray _objectAtIndex:] CGImageSourceCreateImageAtIndex crash randomly HOT 1
- Please bump tiny to 1.5.1 and push new pod HOT 5
- It doesn't work with AFN 3.0+?
- HowTochangeDifferentGif
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from olimageview.