mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-29 04:35:36 +08:00
Improved and generalized image thumbnail decoding logic
Reviewed By: jspahrsummers Differential Revision: D2631934 fb-gh-sync-id: 3ddea328dcb0fc84b9d7b20708324f0b515f1b7f
This commit is contained in:
committed by
facebook-github-bot-2
parent
4b78ed2123
commit
2eb8068cf1
@@ -9,6 +9,9 @@
|
||||
|
||||
#import "RCTImageUtils.h"
|
||||
|
||||
#import <ImageIO/ImageIO.h>
|
||||
#import <tgmath.h>
|
||||
|
||||
#import "RCTLog.h"
|
||||
|
||||
static CGFloat RCTCeilValue(CGFloat value, CGFloat scale)
|
||||
@@ -193,3 +196,69 @@ BOOL RCTUpscalingRequired(CGSize sourceSize, CGFloat sourceScale,
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXTERN CGSize RCTSizeInPixels(CGSize pointSize, CGFloat scale)
|
||||
{
|
||||
return (CGSize){
|
||||
ceil(pointSize.width * scale),
|
||||
ceil(pointSize.height * scale),
|
||||
};
|
||||
}
|
||||
|
||||
RCT_EXTERN UIImage *RCTDecodeImageWithData(NSData *data,
|
||||
CGSize destSize,
|
||||
CGFloat destScale,
|
||||
UIViewContentMode resizeMode)
|
||||
{
|
||||
CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
|
||||
if (!sourceRef) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// get original image size
|
||||
CGSize sourceSize;
|
||||
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(sourceRef, 0, NULL);
|
||||
if (!imageProperties) {
|
||||
CFRelease(sourceRef);
|
||||
return nil;
|
||||
}
|
||||
NSNumber *width = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
|
||||
NSNumber *height = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
|
||||
sourceSize = (CGSize){width.doubleValue, height.doubleValue};
|
||||
CFRelease(imageProperties);
|
||||
|
||||
if (CGSizeEqualToSize(destSize, CGSizeZero)) {
|
||||
destSize = sourceSize;
|
||||
}
|
||||
|
||||
// calculate target size
|
||||
CGSize targetSize = RCTTargetSize(sourceSize, 1, destSize, destScale, resizeMode, YES);
|
||||
CGSize targetPixelSize = RCTSizeInPixels(targetSize, destScale);
|
||||
CGFloat maxPixelSize = fmax(fmin(sourceSize.width, targetPixelSize.width),
|
||||
fmin(sourceSize.height, targetPixelSize.height));
|
||||
|
||||
NSDictionary *options = @{
|
||||
(id)kCGImageSourceShouldAllowFloat: @YES,
|
||||
(id)kCGImageSourceCreateThumbnailWithTransform: @YES,
|
||||
(id)kCGImageSourceCreateThumbnailFromImageAlways: @YES,
|
||||
(id)kCGImageSourceThumbnailMaxPixelSize: @(maxPixelSize),
|
||||
};
|
||||
|
||||
// get thumbnail
|
||||
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(sourceRef, 0, (__bridge CFDictionaryRef)options);
|
||||
CFRelease(sourceRef);
|
||||
if (!imageRef) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
//adjust scale
|
||||
size_t actualWidth = CGImageGetWidth(imageRef);
|
||||
CGFloat scale = actualWidth / targetSize.width;
|
||||
|
||||
// return image
|
||||
UIImage *image = [UIImage imageWithCGImage:imageRef
|
||||
scale:scale
|
||||
orientation:UIImageOrientationUp];
|
||||
CGImageRelease(imageRef);
|
||||
return image;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user