ALAsset 库 + 文档目录图像?

Posted

技术标签:

【中文标题】ALAsset 库 + 文档目录图像?【英文标题】:ALAsset Library + Document Directory images? 【发布时间】:2013-07-03 04:34:12 【问题描述】:

我的应用文档库中有很多图像。我想显示文档目录图像的缩略图。

我正在使用以下代码。

UIImage *thumbImage=[UIImage imageWithContentsOfFile:strImagePath];
if (thumbImage) 
    [thubImageView setImage:thumbImage];

它对我有用,但问题是应用程序由于内存警告而冻结和崩溃。

我已经尝试过 [1]:https://github.com/SlaunchaMan/GCDExample"GCDExample" 但我得到了相同的结果。

ALAsset 库用于获取缩略图。但我不知道如何将它与文档目录图像一起使用。

还有没有其他方法可以在没有内存警告的情况下显示缩略图。

提前致谢。

【问题讨论】:

您使用哪种类型的视图来显示图像列表? UICollectionView、UITableView 还是别的什么? 我正在使用 UITableView.. 您应该只加载当时在屏幕上实际可见的图像。此外,您应该考虑将缩略图图像保存到磁盘,这样您就不必加载全尺寸图像并即时缩小。 【参考方案1】:

类似的问题已经回答here

你可以使用方法

- (UIImage *)thumbnailImage:(NSInteger)thumbnailSize
      transparentBorder:(NSUInteger)borderSize
           cornerRadius:(NSUInteger)cornerRadius
   interpolationQuality:(CGInterpolationQuality)quality;

用于创建缩略图。 UIImage 类别可用here

希望这会有所帮助。

【讨论】:

【参考方案2】:

如果没有看到更多代码,很难更准确地回答这个问题,但这个问题的一般解决方案是在显示表格单元格时延迟加载所需的图像,并确保图像足够小留在记忆中。

提供的GCDExample 使用全局 GCD 队列执行此操作。我不推荐这种方法,将并发队列与 I/O 结合使用会导致意外的线程爆炸。请参阅这篇出色的 Mike Ash 文章以获得非常详细的分析。在这里使用串行 GCD 队列是一种更明智的方法。

【讨论】:

【参考方案3】:

制作任何大小的所有图像缩略图例如:临时目录中的 80x80 在所需的程序区域中使用它们,然后记住在完成任务的情况下删除这些临时目录。

这个类别的实现代码会帮助你:

#import "UIImage+Resize.h"
@implementation UIImage (ResizeCategory)

-(UIImage*)resizedImageToSize:(CGSize)dstSize

    CGImageRef imgRef = self.CGImage;
    // the below values are regardless of orientation : for UIImages from Camera, width>height (landscape)
    CGSize  srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which is dependant on the imageOrientation)!

    CGFloat scaleRatio = dstSize.width / srcSize.width;

    UIImageOrientation orient = self.imageOrientation;
    CGAffineTransform transform = CGAffineTransformIdentity;
    switch(orient) 

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(srcSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(srcSize.width, srcSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, srcSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            dstSize = CGSizeMake(dstSize.height, dstSize.width);
            transform = CGAffineTransformMakeTranslation(srcSize.height, srcSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2);
            break;

        case UIImageOrientationLeft: //EXIF = 6  
            dstSize = CGSizeMake(dstSize.height, dstSize.width);
            transform = CGAffineTransformMakeTranslation(0.0, srcSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2);
            break; 

        case UIImageOrientationRightMirrored: //EXIF = 7  
            dstSize = CGSizeMake(dstSize.height, dstSize.width);
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight: //EXIF = 8  
            dstSize = CGSizeMake(dstSize.height, dstSize.width);
            transform = CGAffineTransformMakeTranslation(srcSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;  

        default:  
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];  


      

    // The actual resize: draw the image on a new context, applying a transform matrix

    UIGraphicsBeginImageContext(dstSize);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) 
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -srcSize.height, 0);
     else   
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -srcSize.height);
    

    CGContextConcatCTM(context, transform);

    // we use srcSize (and not dstSize) as the size to specify is in user space (and we use the CTM to apply a scaleRatio)
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, srcSize.width, srcSize.height), imgRef);
    UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return resizedImage;

-(UIImage*)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale

    // get the image size (independant of imageOrientation)
    CGImageRef imgRef = self.CGImage;
    CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which depends on the imageOrientation)!

    // adjust boundingSize to make it independant on imageOrientation too for farther computations
    UIImageOrientation orient = self.imageOrientation;  
    switch (orient) 
        case UIImageOrientationLeft:
        case UIImageOrientationRight:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            boundingSize = CGSizeMake(boundingSize.height, boundingSize.width);
            break;
        default:
            // NOP
            break;
    

    // Compute the target CGRect in order to keep aspect-ratio
    CGSize dstSize;

    if ( !scale && (srcSize.width < boundingSize.width) && (srcSize.height < boundingSize.height) ) 
        ////NSLog(@"Image is smaller, and we asked not to scale it in this case (scaleIfSmaller:NO)");
        dstSize = srcSize; // no resize (we could directly return 'self' here, but we draw the image anyway to take image orientation into account)
     else         
        CGFloat wRatio = boundingSize.width / srcSize.width;
        CGFloat hRatio = boundingSize.height / srcSize.height;

        if (wRatio < hRatio) 
            ////NSLog(@"Width imposed, Height scaled ; ratio = %f",wRatio);
            dstSize = CGSizeMake(boundingSize.width, srcSize.height * wRatio);
         else 
            ////NSLog(@"Height imposed, Width scaled ; ratio = %f",hRatio);
            dstSize = CGSizeMake(srcSize.width * hRatio, boundingSize.height);
        
    

    return [self resizedImageToSize:dstSize];


@end

内存问题会自动解决。

【讨论】:

以上是关于ALAsset 库 + 文档目录图像?的主要内容,如果未能解决你的问题,请参考以下文章

[库assetForURL:url resultBlock:^(ALAsset *asset) 不执行

如何使用 ALAsset 获得图像的裁剪版本?

我如何知道资产库中存在 ALAsset 的 NSURL?

ALAsset Library 减小图像的大小,同时将其保存在照片库中

ALAsset 图像大小

带有 ALAsset 缩略图的低清晰度