图片解码优化

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"xxx"];
    
//    UIImage * image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"2268688312388037455.jpg" ofType:nil]];
    UIImage * image = [UIImage imageNamed:@"2268688312388037455.jpg"];
    UIImageView * imageView = [[UIImageView alloc]initWithImage:image];
    imageView.frame = CGRectMake(0, 0, 300, 300);
//    UIImage * image1 = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"2268688312388037455.jpg" ofType:nil]];
    UIImage * image1 = [UIImage imageNamed:@"2268688312388037455.jpg"];
    UIImageView * imageView1 = [[UIImageView alloc]initWithImage:image1];
    imageView.frame = CGRectMake(300, 0, 300, 300);
    [cell addSubview:imageView];
    [cell addSubview:imageView1];
    return cell;
}

滑动发现,imageNamed只是刚开始略有卡顿,对解码数据缓存后就很顺滑了,但是imageWithContentsOfFile 一直都比较卡顿

但是这些方法的解码操作都是在主线完成的,而图片解码又是一个很消耗性能的操作

SDWebImage的做法是把解码操作从主线程移到子线程,让耗时的解码操作不占用主线程的时间

static const size_t kBytesPerPixel = 4;
static const size_t kBitsPerComponent = 8;
+ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image {
    if (![UIImage shouldDecodeImage:image]) {
        return image;
    }
    
    // autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
    // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
    //新建自动释放池,将bitmap context和临时变量都添加到池中在方法末尾自动释放以防止内存警告
    @autoreleasepool{
        //获取传入的UIImage对应的CGImageRef(位图)
        CGImageRef imageRef = image.CGImage;
        //获取彩色空间
        CGColorSpaceRef colorspaceRef = [UIImage colorSpaceForImageRef:imageRef];
        
        //获取高和宽
        size_t width = CGImageGetWidth(imageRef);
        size_t height = CGImageGetHeight(imageRef);
        //static const size_t kBytesPerPixel = 4
        // 每个像素占4个字节大小 共32位 (RGBA)
        size_t bytesPerRow = kBytesPerPixel * width;

        // kCGImageAlphaNone is not supported in CGBitmapContextCreate.
        // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
        // to create bitmap graphics contexts without alpha info.
        //初始化bitmap graphics context 上下文
        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
        //将CGImageRef对象画到上面生成的上下文中,且将alpha通道移除
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
        //使用上下文创建位图
        CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
        //从位图创建UIImage对象
        UIImage *imageWithoutAlpha = [UIImage imageWithCGImage:imageRefWithoutAlpha
                                                         scale:image.scale
                                                   orientation:image.imageOrientation];
        //释放CG对象
        CGContextRelease(context);
        CGImageRelease(imageRefWithoutAlpha);
        
        return imageWithoutAlpha;
    }
}

上面操作是在子线程中进行的

就是把UIImage绘制出来的图像再保存起来就完成了这个解码的过程

CGImageRef 就是位图(bmp)

https://www.jishudog.com/1294/html

你可能感兴趣的:(图片解码优化)