Skip to content

Commit 5864b77

Browse files
authored
Merge pull request #70 from SDWebImage/feat/encode_with_frames
Adopt 5.15.0's encodedDataWithFrames API
2 parents 4416805 + b0a7178 commit 5864b77

File tree

4 files changed

+56
-8
lines changed

4 files changed

+56
-8
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ let image = SDImageWebPCoder.shared.decodedImage(with: data, options: [.decodeTh
176176
// WebP image encoding
177177
UIImage *image;
178178
NSData *webpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:nil];
179+
// Animated encoding
180+
NSArray<SDImageFrames *> *frames;
181+
NSData *awebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithFrames:frames loopCount:0 format:SDImageFormatWebP options:nil];
179182
// Encode Quality
180183
NSData *lossyWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:@{SDImageCoderEncodeCompressionQuality : @(0.1)}]; // [0, 1] compression quality
181184
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
187190
// WebP image encoding
188191
let image: UIImage
189192
let webpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: nil)
193+
// Animated encoding
194+
let frames: [SDImageFrame]
195+
let awebpData = SDImageWebPCoder.shared.encodedData(with: frames, loopCount: 0, format: .webP, options: nil)
190196
// Encode Quality
191197
let lossyWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: [.encodeCompressionQuality: 0.1]) // [0, 1] compression quality
192198
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:
212218

213219
See more documentation in [SDWebImage Wiki - Coders](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420)
214220

221+
### Animated WebP Encoding (0.10+)
222+
223+
+ Objective-c
224+
225+
```objective-c
226+
// Animated encoding
227+
NSMutableArray<SDImageFrames *> *frames = [NSMutableArray array];
228+
for (size_t i = 0; i < images.count; i++) {
229+
SDImageFrame *frame = [SDImageFrame frameWithImage:images[i] duration:0.1];
230+
[frames appendObject:frame];
231+
}
232+
NSData *awebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithFrames:frames loopCount:0 format:SDImageFormatWebP options:nil];
233+
```
234+
235+
+ Swift
236+
237+
```swift
238+
// Animated encoding
239+
var frames: [SDImageFrame] = []
240+
for i in [0..<images.count] {
241+
let frame = SDImageFrame(image: images[i], duration: 0.1)
242+
frames.append(frame)
243+
}
244+
let awebpData = SDImageWebPCoder.shared.encodedData(with: frames, loopCount: 0, format: .webP, options: nil)
245+
```
246+
215247
### Advanced WebP codec options (0.8+)
216248

217249
The WebP codec [libwebp](https://developers.google.com/speed/webp/docs/api) we use, supports some advanced control options for encoding/decoding. You can pass them to libwebp by using the wrapper top level API:

SDWebImageWebPCoder.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This is a SDWebImage coder plugin to support WebP image.
2727
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1 WEBP_USE_INTRINSICS=1',
2828
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src'
2929
}
30-
s.dependency 'SDWebImage/Core', '~> 5.13'
30+
s.dependency 'SDWebImage/Core', '~> 5.15'
3131
s.dependency 'libwebp', '~> 1.0'
3232

3333
end

SDWebImageWebPCoder/Classes/SDImageWebPCoder.m

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,24 @@ - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format o
595595
if (!image) {
596596
return nil;
597597
}
598+
NSArray<SDImageFrame *> *frames = [SDImageCoderHelper framesFromAnimatedImage:image];
599+
if (!frames || frames.count == 0) {
600+
SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:0];
601+
frames = @[frame];
602+
}
603+
return [self encodedDataWithFrames:frames loopCount:image.sd_imageLoopCount format:format options:options];
604+
}
605+
606+
- (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(NSUInteger)loopCount format:(SDImageFormat)format options:(SDImageCoderOptions *)options {
607+
UIImage *image = frames.firstObject.image; // Primary image
608+
if (!image) {
609+
return nil;
610+
}
611+
CGImageRef imageRef = image.CGImage;
612+
if (!imageRef) {
613+
// Earily return, supports CGImage only
614+
return nil;
615+
}
598616

599617
NSData *data;
600618

@@ -615,12 +633,11 @@ - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format o
615633
if (options[SDImageCoderEncodeMaxFileSize]) {
616634
maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue];
617635
}
618-
NSArray<SDImageFrame *> *frames = [SDImageCoderHelper framesFromAnimatedImage:image];
619636

620637
BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue];
621-
if (encodeFirstFrame || frames.count == 0) {
638+
if (encodeFirstFrame || frames.count <= 1) {
622639
// for static single webp image
623-
data = [self sd_encodedWebpDataWithImage:image.CGImage
640+
data = [self sd_encodedWebpDataWithImage:imageRef
624641
quality:compressionQuality
625642
maxPixelSize:maxPixelSize
626643
maxFileSize:maxFileSize
@@ -652,9 +669,8 @@ - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format o
652669
}
653670
}
654671

655-
int loopCount = (int)image.sd_imageLoopCount;
656672
WebPMuxAnimParams params = { .bgcolor = 0,
657-
.loop_count = loopCount
673+
.loop_count = (int)loopCount
658674
};
659675
if (WebPMuxSetAnimationParams(mux, &params) != WEBP_MUX_OK) {
660676
WebPMuxDelete(mux);

Tests/SDWebImageWebPCoderTests.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ - (void)test34StaticImageNotCreateCGContext {
193193
NSURL *staticWebPURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageStatic" withExtension:@"webp"];
194194
NSData *data = [NSData dataWithContentsOfURL:staticWebPURL];
195195
SDImageWebPCoder *coder = [[SDImageWebPCoder alloc] initWithAnimatedImageData:data options:nil];
196-
XCTAssertTrue(coder.animatedImageFrameCount == 1);
196+
XCTAssertTrue(coder.animatedImageFrameCount == 0);
197197
UIImage *image = [coder animatedImageFrameAtIndex:0];
198-
XCTAssertNotNil(image);
198+
XCTAssertNil(image);
199199
Ivar ivar = class_getInstanceVariable(coder.class, "_canvas");
200200
CGContextRef canvas = ((CGContextRef (*)(id, Ivar))object_getIvar)(coder, ivar);
201201
XCTAssert(canvas == NULL);

0 commit comments

Comments
 (0)