Fix the maxPixelSize for animated images, update the readme
This commit is contained in:
parent
e71bbf239c
commit
f798b89fc2
|
@ -37,6 +37,7 @@ FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodePreserveAs
|
|||
/**
|
||||
A CGSize value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.preserveAspectRatio`) the value size.
|
||||
Defaults to CGSizeZero, which means no thumbnail generation at all.
|
||||
@note Supports for animated image as well.
|
||||
@note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.
|
||||
@note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`.
|
||||
*/
|
||||
|
@ -62,8 +63,10 @@ FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeCompressio
|
|||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeBackgroundColor;
|
||||
|
||||
/**
|
||||
A CGSize value indicating the max image resolution in pixels during encoding. For vector image, this also effect the output vector data information about width and height. The encoder will not generate the encoded image larger than this limit. Note it always use the aspect ratio of input image.
|
||||
A CGSize value indicating the max image resolution in pixels during encoding. For vector image, this also effect the output vector data information about width and height. The encoder will not generate the encoded image larger than this limit. Note it always use the aspect ratio of input image..
|
||||
Defaults to CGSizeZero, which means no max size limit at all.
|
||||
@note Supports for animated image as well.
|
||||
@note The ouput image's width is limited to pixel size's width, the output image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.
|
||||
@note works for `SDImageCoder`
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeMaxPixelSize;
|
||||
|
|
|
@ -452,21 +452,23 @@ static NSString * kSDCGImageSourceRasterizationDPI = @"kCGImageSourceRasterizati
|
|||
}
|
||||
NSUInteger pixelWidth = CGImageGetWidth(imageRef);
|
||||
NSUInteger pixelHeight = CGImageGetHeight(imageRef);
|
||||
CGFloat finalPixelSize = 0;
|
||||
if (maxPixelSize.width > 0 && maxPixelSize.height > 0 && pixelWidth > 0 && pixelHeight > 0) {
|
||||
CGFloat pixelRatio = pixelWidth / pixelHeight;
|
||||
CGFloat maxPixelSizeRatio = maxPixelSize.width / maxPixelSize.height;
|
||||
CGFloat finalPixelSize;
|
||||
if (pixelRatio > maxPixelSizeRatio) {
|
||||
finalPixelSize = maxPixelSize.width;
|
||||
} else {
|
||||
finalPixelSize = maxPixelSize.height;
|
||||
}
|
||||
properties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize);
|
||||
}
|
||||
|
||||
BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue];
|
||||
if (encodeFirstFrame || frames.count == 0) {
|
||||
// for static single images
|
||||
if (finalPixelSize > 0) {
|
||||
properties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize);
|
||||
}
|
||||
CGImageDestinationAddImage(imageDestination, imageRef, (__bridge CFDictionaryRef)properties);
|
||||
} else {
|
||||
// for animated images
|
||||
|
@ -479,7 +481,11 @@ static NSString * kSDCGImageSourceRasterizationDPI = @"kCGImageSourceRasterizati
|
|||
SDImageFrame *frame = frames[i];
|
||||
NSTimeInterval frameDuration = frame.duration;
|
||||
CGImageRef frameImageRef = frame.image.CGImage;
|
||||
NSDictionary *frameProperties = @{self.class.dictionaryProperty : @{self.class.delayTimeProperty : @(frameDuration)}};
|
||||
NSMutableDictionary *frameProperties = [NSMutableDictionary dictionary];
|
||||
frameProperties[self.class.dictionaryProperty] = @{self.class.delayTimeProperty : @(frameDuration)};
|
||||
if (finalPixelSize > 0) {
|
||||
frameProperties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize);
|
||||
}
|
||||
CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,6 +271,25 @@ withLocalImageURL:(NSURL *)imageUrl
|
|||
#if SD_UIKIT
|
||||
expect(outputImage.images.count).to.equal(inputImage.images.count);
|
||||
#endif
|
||||
|
||||
// check max pixel size encoding with scratch
|
||||
CGFloat maxWidth = 50;
|
||||
CGFloat maxHeight = 50;
|
||||
CGFloat maxRatio = maxWidth / maxHeight;
|
||||
CGSize maxPixelSize;
|
||||
if (ratio > maxRatio) {
|
||||
maxPixelSize = CGSizeMake(maxWidth, round(maxWidth / ratio));
|
||||
} else {
|
||||
maxPixelSize = CGSizeMake(round(maxHeight * ratio), maxHeight);
|
||||
}
|
||||
NSData *outputMaxImageData = [coder encodedDataWithImage:inputImage format:encodingFormat options:@{SDImageCoderEncodeMaxPixelSize : @(CGSizeMake(maxWidth, maxHeight))}];
|
||||
UIImage *outputMaxImage = [coder decodedImageWithData:outputMaxImageData options:nil];
|
||||
// Image/IO's thumbnail API does not always use round to preserve precision, we check ABS <= 1
|
||||
expect(ABS(outputMaxImage.size.width - maxPixelSize.width) <= 1);
|
||||
expect(ABS(outputMaxImage.size.height - maxPixelSize.height) <= 1);
|
||||
#if SD_UIKIT
|
||||
expect(outputMaxImage.images.count).to.equal(inputImage.images.count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue