diff --git a/README.md b/README.md index 70ae978..aa727c4 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,9 @@ let image = SDImageWebPCoder.shared.decodedImage(with: data, options: [.decodeTh // WebP image encoding UIImage *image; NSData *webpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:nil]; +// Animated encoding +NSArray *frames; +NSData *awebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithFrames:frames loopCount:0 format:SDImageFormatWebP options:nil]; // Encode Quality NSData *lossyWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:@{SDImageCoderEncodeCompressionQuality : @(0.1)}]; // [0, 1] compression quality NSData *limitedWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:@{SDImageCoderEncodeMaxFileSize : @(1024 * 10)}]; // v0.6.0 feature, limit output file size <= 10KB @@ -187,6 +190,9 @@ NSData *limitedWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:i // WebP image encoding let image: UIImage let webpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: nil) +// Animated encoding +let frames: [SDImageFrame] +let awebpData = SDImageWebPCoder.shared.encodedData(with: frames, loopCount: 0, format: .webP, options: nil) // Encode Quality let lossyWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: [.encodeCompressionQuality: 0.1]) // [0, 1] compression quality let limitedWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: [.encodeMaxFileSize: 1024 * 10]) // v0.6.0 feature, limit output file size <= 10KB @@ -212,6 +218,32 @@ let thumbnailWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: See more documentation in [SDWebImage Wiki - Coders](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420) +### Animated WebP Encoding (0.10+) + ++ Objective-c + +```objective-c +// Animated encoding +NSMutableArray *frames = [NSMutableArray array]; +for (size_t i = 0; i < images.count; i++) { + SDImageFrame *frame = [SDImageFrame frameWithImage:images[i] duration:0.1]; + [frames appendObject:frame]; +} +NSData *awebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithFrames:frames loopCount:0 format:SDImageFormatWebP options:nil]; +``` + ++ Swift + +```swift +// Animated encoding +var frames: [SDImageFrame] = [] +for i in [0.. '$(inherited) SD_WEBP=1 WEBP_USE_INTRINSICS=1', 'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src' } - s.dependency 'SDWebImage/Core', '~> 5.13' + s.dependency 'SDWebImage/Core', '~> 5.15' s.dependency 'libwebp', '~> 1.0' end diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m index ebf7dcb..da7d48e 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m @@ -595,6 +595,24 @@ else OSSpinLockUnlock(&lock##_deprecated); if (!image) { return nil; } + NSArray *frames = [SDImageCoderHelper framesFromAnimatedImage:image]; + if (!frames || frames.count == 0) { + SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:0]; + frames = @[frame]; + } + return [self encodedDataWithFrames:frames loopCount:image.sd_imageLoopCount format:format options:options]; +} + +- (NSData *)encodedDataWithFrames:(NSArray *)frames loopCount:(NSUInteger)loopCount format:(SDImageFormat)format options:(SDImageCoderOptions *)options { + UIImage *image = frames.firstObject.image; // Primary image + if (!image) { + return nil; + } + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + // Earily return, supports CGImage only + return nil; + } NSData *data; @@ -615,12 +633,11 @@ else OSSpinLockUnlock(&lock##_deprecated); if (options[SDImageCoderEncodeMaxFileSize]) { maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue]; } - NSArray *frames = [SDImageCoderHelper framesFromAnimatedImage:image]; BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue]; - if (encodeFirstFrame || frames.count == 0) { + if (encodeFirstFrame || frames.count <= 1) { // for static single webp image - data = [self sd_encodedWebpDataWithImage:image.CGImage + data = [self sd_encodedWebpDataWithImage:imageRef quality:compressionQuality maxPixelSize:maxPixelSize maxFileSize:maxFileSize @@ -652,9 +669,8 @@ else OSSpinLockUnlock(&lock##_deprecated); } } - int loopCount = (int)image.sd_imageLoopCount; WebPMuxAnimParams params = { .bgcolor = 0, - .loop_count = loopCount + .loop_count = (int)loopCount }; if (WebPMuxSetAnimationParams(mux, ¶ms) != WEBP_MUX_OK) { WebPMuxDelete(mux);