Change the behavior, supports to scale down to at least 4 Bytes (1x1 pixels) image. Does not hard-code limit 1MB
This commit is contained in:
parent
c1a5546350
commit
01e5e429fd
|
@ -91,7 +91,8 @@
|
|||
+ (UIImage * _Nullable)decodedImageWithImage:(UIImage * _Nullable)image;
|
||||
|
||||
/**
|
||||
Return the decoded and probably scaled down image by the provided image. If the image is large than the limit size, will try to scale down. Or just works as `decodedImageWithImage:`
|
||||
Return the decoded and probably scaled down image by the provided image. If the image pixels bytes size large than the limit bytes, will try to scale down. Or just works as `decodedImageWithImage:`, never scale up.
|
||||
@warning You should not pass a too smaller bytes limit, the suggestion value should be larger than 1MB. We use Tile Decoding to avoid OOM, however, this will consume much more CPU time because we need to iterate and draw each tile (which may be hundreds).
|
||||
|
||||
@param image The image to be decoded and scaled down
|
||||
@param bytes The limit bytes size. Provide 0 to use the build-in limit.
|
||||
|
@ -101,7 +102,7 @@
|
|||
|
||||
/**
|
||||
Control the default limit bytes to scale down largest images.
|
||||
This value must be larger than or equal to 1MB. Defaults to 60MB on iOS/tvOS, 90MB on macOS, 30MB on watchOS.
|
||||
This value must be larger than 4 Bytes (at least 1x1 pixel). Defaults to 60MB on iOS/tvOS, 90MB on macOS, 30MB on watchOS.
|
||||
*/
|
||||
@property (class, readwrite) NSUInteger defaultScaleDownLimitBytes;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ static const size_t kBytesPerPixel = 4;
|
|||
static const size_t kBitsPerComponent = 8;
|
||||
|
||||
static const CGFloat kBytesPerMB = 1024.0f * 1024.0f;
|
||||
static const CGFloat kPixelsPerMB = kBytesPerMB / kBytesPerPixel;
|
||||
/*
|
||||
* Defines the maximum size in MB of the decoded image when the flag `SDWebImageScaleDownLargeImages` is set
|
||||
* Suggested value for iPad1 and iPhone 3GS: 60.
|
||||
|
@ -379,8 +378,8 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
// see kDestImageSizeMB, and how it relates to destTotalPixels.
|
||||
CGFloat imageScale = sqrt(destTotalPixels / sourceTotalPixels);
|
||||
CGSize destResolution = CGSizeZero;
|
||||
destResolution.width = (int)(sourceResolution.width * imageScale);
|
||||
destResolution.height = (int)(sourceResolution.height * imageScale);
|
||||
destResolution.width = MAX(1, (int)(sourceResolution.width * imageScale));
|
||||
destResolution.height = MAX(1, (int)(sourceResolution.height * imageScale));
|
||||
|
||||
// device color space
|
||||
CGColorSpaceRef colorspaceRef = [self colorSpaceGetDeviceRGB];
|
||||
|
@ -419,7 +418,7 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
// The source tile height is dynamic. Since we specified the size
|
||||
// of the source tile in MB, see how many rows of pixels high it
|
||||
// can be given the input image width.
|
||||
sourceTile.size.height = (int)(tileTotalPixels / sourceTile.size.width );
|
||||
sourceTile.size.height = MAX(1, (int)(tileTotalPixels / sourceTile.size.width));
|
||||
sourceTile.origin.x = 0.0f;
|
||||
// The output tile is the same proportions as the input tile, but
|
||||
// scaled to image scale.
|
||||
|
@ -485,7 +484,7 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
}
|
||||
|
||||
+ (void)setDefaultScaleDownLimitBytes:(NSUInteger)defaultScaleDownLimitBytes {
|
||||
if (defaultScaleDownLimitBytes < kBytesPerMB) {
|
||||
if (defaultScaleDownLimitBytes < kBytesPerPixel) {
|
||||
return;
|
||||
}
|
||||
kDestImageLimitBytes = defaultScaleDownLimitBytes;
|
||||
|
@ -595,27 +594,16 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
return NO;
|
||||
}
|
||||
CGFloat destTotalPixels;
|
||||
CGFloat tileTotalPixels;
|
||||
if (bytes == 0) {
|
||||
bytes = kDestImageLimitBytes;
|
||||
bytes = [self defaultScaleDownLimitBytes];
|
||||
}
|
||||
destTotalPixels = bytes / kBytesPerPixel;
|
||||
if (destTotalPixels <= kPixelsPerMB) {
|
||||
// Too small to scale down
|
||||
return NO;
|
||||
}
|
||||
float imageScale = destTotalPixels / sourceTotalPixels;
|
||||
if (imageScale < 1) {
|
||||
shouldScaleDown = YES;
|
||||
} else {
|
||||
shouldScaleDown = NO;
|
||||
}
|
||||
// Add a protect when tile rectangle is too small to calculate
|
||||
// The tile rectangle width equals to image's width, height should be at least 1 pixel
|
||||
tileTotalPixels = destTotalPixels / 3;
|
||||
if (tileTotalPixels < sourceResolution.width * 1) {
|
||||
shouldScaleDown = NO;
|
||||
}
|
||||
|
||||
return shouldScaleDown;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue