zoukankan      html  css  js  c++  java
  • iOS8下新框架 photoKit 之模仿 ALAsset 取 fullScreenImage 图片,解决内存暴增问题

    转载请注明出处:http://www.cnblogs.com/shisishao/p/5737228.html

    我们知道 photoKit 框架,官方是说用起来更方便,更快捷。但是其中的坑,只有用的人才知道是有多么的多,真是谁用谁知道啊!

    photoKit 框架提供的对象是 PHAsset, 而之前的 用ALAssetsLibrary 取的是ALAsset对象,我们知道只要取的ALAsset对象,取图片是很简单的直接对象中就包含有图片对象,取大图:(UIImage *temp_img = [UIImage imageWithCGImage:temp_asset.defaultRepresentation.fullScreenImage];),取缩略图:(UIImage *temp_img = [UIImage imageWithCGImage:asset.aspectRatioThumbnail];) ,但是如果用PHAsset对象取图,只能通过 requestImageForAsset 方法回调,如果穿的参数 PHImageRequestOptions 的synchronous属性为YES返回的是原图,而原图是很大的,如果同时取多张图片,内存会暴增,有可能导致闪退,所以这里这里就模仿 ALAsset 通过获取图片的大小来设置参数,从而获取合适的图片:

    - (UIImage *)getImageWithBaseAsset:(id)asset {

        __block UIImage *resultImage = nil;

        if ([asset isKindOfClass:[PHAsset class]]) {

            PHAsset *tempAsset = asset;

            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];

            // 下面的回调会返回两次 该属性设置YES 只返回一次

            options.synchronous = YES;

            options.resizeMode = PHImageRequestOptionsResizeModeFast;

            CGFloat scale = [UIScreen mainScreen].scale;

            CGSize size = CGSizeMake(tempAsset.pixelWidth, tempAsset.pixelHeight);

            NSLog(@"###, %f, %f, %f, %f", [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height, size.width, size.height);

            CGFloat scale_width = [UIScreen mainScreen].bounds.size.width*scale;

            CGFloat scale_height = [UIScreen mainScreen].bounds.size.height*scale;

       //  通过设置合适的图片参数,防止内存过高问题(关键点)

            if (tempAsset.pixelWidth > scale_width && tempAsset.pixelHeight > scale_height) {

                if (tempAsset.pixelWidth >= tempAsset.pixelHeight) {

                    size = CGSizeMake(scale_height, (NSInteger)(scale_height/tempAsset.pixelWidth*tempAsset.pixelHeight));

                } else {

                    size = CGSizeMake((NSInteger)(scale_height/tempAsset.pixelHeight*tempAsset.pixelWidth), scale_height);

                }

            }

            

            WS(weakSelf);

            [[PHImageManager defaultManager] requestImageForAsset:tempAsset targetSize:size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {

                NSLog(@"### index");

                UIImage *temp_img = result;

                resultImage = [weakSelf fixOrientation:temp_img];

            }];

        }

        return resultImage;

    }

    // 修正图片转向

    - (UIImage *)fixOrientation:(UIImage *)aImage {

        if (!self.shouldFixOrientation) return aImage;

        

        // No-op if the orientation is already correct

        if (aImage.imageOrientation == UIImageOrientationUp)

            return aImage;

        

        // We need to calculate the proper transformation to make the image upright.

        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.

        CGAffineTransform transform = CGAffineTransformIdentity;

        

        switch (aImage.imageOrientation) {

            case UIImageOrientationDown:

            case UIImageOrientationDownMirrored:

                transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);

                transform = CGAffineTransformRotate(transform, M_PI);

                break;

                

            case UIImageOrientationLeft:

            case UIImageOrientationLeftMirrored:

                transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);

                transform = CGAffineTransformRotate(transform, M_PI_2);

                break;

                

            case UIImageOrientationRight:

            case UIImageOrientationRightMirrored:

                transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);

                transform = CGAffineTransformRotate(transform, -M_PI_2);

                break;

            default:

                break;

        }

        

        switch (aImage.imageOrientation) {

            case UIImageOrientationUpMirrored:

            case UIImageOrientationDownMirrored:

                transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);

                transform = CGAffineTransformScale(transform, -1, 1);

                break;

                

            case UIImageOrientationLeftMirrored:

            case UIImageOrientationRightMirrored:

                transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);

                transform = CGAffineTransformScale(transform, -1, 1);

                break;

            default:

                break;

        }

        

        // Now we draw the underlying CGImage into a new context, applying the transform

        // calculated above.

        CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,

                                                 CGImageGetBitsPerComponent(aImage.CGImage), 0,

                                                 CGImageGetColorSpace(aImage.CGImage),

                                                 CGImageGetBitmapInfo(aImage.CGImage));

        CGContextConcatCTM(ctx, transform);

        switch (aImage.imageOrientation) {

            case UIImageOrientationLeft:

            case UIImageOrientationLeftMirrored:

            case UIImageOrientationRight:

            case UIImageOrientationRightMirrored:

                // Grr...

                CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);

                break;

                

            default:

                CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);

                break;

        }

        

        // And now we just create a new UIImage from the drawing context

        CGImageRef cgimg = CGBitmapContextCreateImage(ctx);

        UIImage *img = [UIImage imageWithCGImage:cgimg];

        CGContextRelease(ctx);

        CGImageRelease(cgimg);

        return img;

    }

    这样取出的图片分辨率跟 ALAsse.defaultRepresentation.fullScreenImage 取到的图片分辨率一样,而且不会导致内存暴增,还有一点是通过回调取到的图片,图片的方向信息有可能是拍照时的方向,所以 fixOrientation 方法是用来修正图片方向的。

  • 相关阅读:
    web自动化中的三种切换---alert弹框切换
    web自动化中的三种切换--窗口切换
    web自动化中的三种切换---iframe
    web元素定位中的三种等待方法
    web自动化浏览器chrome和驱动chromedriver
    selenium安装
    pytest用例标记规则
    键盘事件
    鼠标事件
    控制浏览器
  • 原文地址:https://www.cnblogs.com/shisishao/p/5737228.html
Copyright © 2011-2022 走看看