SDWebImage有感(二)
2017-11-29 本文已影响25人
Mrfengzi
图片解码
为了使图片渲染更加流畅,SDWebImage对下载的图片进行了解码操作。
先看下几个常量
每个像素占用内存多少个字节
static const size_t kBytesPerPixel =4;
表示每一个组件占多少位,因为RGBA,其中R(红色)G(绿色)B(蓝色)A(透明度)是4个组件,每个像素由这4个组件组成,所以每像素就是8*4 = 32位
static const size_t kBitsPerComponent = 8;
1M占的字节数
static const CGFloat kBytesPerMB = 1024.0f * 1024.0f;
1M占的像素数
static const CGFloat kPixelsPerMB = kBytesPerMB / kBytesPerPixel;
思考:
我们可以根据这个计算一张图片解码后的内存大小
图片占用的字节
width*scale*height*scale/tkBytesPerPixel
图片占用多少M
width*scale*height*scale/tkBytesPerPixel/kPixelsPerMB
+ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image {
//过滤有透明因素的图片
if (![UIImage shouldDecodeImage:image]) {
return image;
}
// autorelease 防止内存某一时刻过高,以及内存警告时释放内存
@autoreleasepool{
CGImageRef imageRef = image.CGImage;
//颜色空间
CGColorSpaceRef colorspaceRef = [UIImage colorSpaceForImageRef:imageRef];
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
//计算出每行行的像素数
size_t bytesPerRow = kBytesPerPixel * width;
// kCGImageAlphaNone is not supported in CGBitmapContextCreate.这里创建的contexts是没有透明因素的(位图图形上下文),为了防止渲染控件的时候直接忽略掉其下方的图层
CGContextRef context = CGBitmapContextCreate(NULL,
width,
height,
kBitsPerComponent,
bytesPerRow,
colorspaceRef,
kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
if (context == NULL) {
return image;
}
// Draw the image into the context and retrieve the new bitmap image without alpha
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
//image.imageOrientation由于使用CoreGraphics绘制图片的Y坐标和UIKit的Y坐标相反,这时要要把图片正古来
UIImage *imageWithoutAlpha = [UIImage imageWithCGImage:imageRefWithoutAlpha
scale:image.scale
orientation:image.imageOrientation];
CGContextRelease(context);
CGImageRelease(imageRefWithoutAlpha);
return imageWithoutAlpha;
}
}