iOS开发

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;
    }
}
上一篇下一篇

猜你喜欢

热点阅读