【问题标题】:UICollectionView image on cell memory warning单元格内存警告上的 UICollectionView 图像
【发布时间】:2013-06-18 06:16:30
【问题描述】:

我使用 Xcode 4.6.1、iOS SDK 6.1、ARC 和 Storyboards,测试运行 6.1.3 的设备 iphone 4S

我在配置包含图片的 collectionviewcell 时遇到了一点问题,当我尝试在单元格上添加一些自定义图片时,内存只是每张图片直接跳跃 30-40mb,图片直接在设备相机并保存在文档目录中,也许您可​​以帮助我。

这是我使用的代码:

    --the code to load the images path on an array imagesArray
-(void) llenarArregloImagenes
{
imagesArray=[[NSMutableArray alloc]init];
NSFileManager *fileMgr=[[NSFileManager alloc]init];
NSError * error = nil;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)     lastObject];
//vemos cuantos objetos con la extension .jpg hay
NSArray *contenidoDirectorio=[fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error];
//FILTER THE JPG FILES
contenidoDirectorio = [contenidoDirectorio filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"pathExtension ==[c] %@", @"jpg"]];
//para meter en el arrelo las imagenes
int indice=0;
if([contenidoDirectorio count]>0)
{
for(indice=0;indice<=[contenidoDirectorio count]-1;indice++)
{
    NSString* path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithString:[contenidoDirectorio objectAtIndex:indice]]];
    [imagesArray addObject:path];
}
}

    --end loading images

然后我使用此代码将图像加载到集合视图中

--collection view code to add image to cell
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
             cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Entra a las celdas");
static NSString *identificador=@"celdaImagen";
celdaImagen *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:identificador forIndexPath:indexPath];
UIImage* image = [UIImage imageWithContentsOfFile:[imagesArray objectAtIndex:indexPath.item]];
//myCell.imagen.image = [imagesArray objectAtIndex:indexPath.item];
//comprimir la imagen
//double compressionRatio=1;
//NSData *imgData=UIImageJPEGRepresentation(image,compressionRatio);
//NSLog(@"tamano de la imagen %i",(imgData.length)/1024);
//UIImage *imagenRedimensionada=[[UIImage alloc] initWithData:imgData];
//
NSData *imageData = UIImagePNGRepresentation(image); //png o jpg
NSLog(@"tamano imagen %i",(imageData.length)/1024);
myCell.imagen.image=image;
return myCell;
}
--end of loading images

这是我用来从相机或相机胶卷中保存图像的代码,我必须说我不在乎它是 PNG 还是 JPG,我可以使用任何一个。

--code to save image on documents file 
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];

[self dismissViewControllerAnimated:YES completion:nil];

if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
    UIImage *image = info[UIImagePickerControllerOriginalImage];
        NSData *imageData = UIImageJPEGRepresentation(image,0.009); //png o jpg
        NSLog(@"tamano imagen %i",(imageData.length)/1024);
        NSFileManager *fileMgr=[[NSFileManager alloc]init];
        NSError * error = nil;
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)     lastObject];
        //vemos cuantos objetos con la extension .png hay
        NSArray *contenidoDirectorio=[fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error];
        //contenidoDirectorio = [contenidoDirectorio filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"pathExtension ==[c] %@", @"mov"]];
        NSString *nombreArchivo=[NSString stringWithFormat:@"imagen%i.jpg",[contenidoDirectorio count]] ;
        NSString *path = [documentsDirectory stringByAppendingPathComponent:nombreArchivo];
        //mostramos el contenido del archivo
        NSLog(@"Documents directory: %@", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]);
        //guardamos el archivo
        [imageData writeToFile:path options:NSDataWritingAtomic error:&error];
        //volvemos a cargar los datos del collectionview
        [self llenarArregloImagenes];
        //metemos la ruta completa de la imagen
        //double compressionRatio=0.1;
        //NSData *imgData=UIImageJPEGRepresentation(image,compressionRatio);
        //UIImage *imagenRedimensionada=[[UIImage alloc] initWithData:imgData];
        //
        //[imagesArray addObject:imagenRedimensionada];
        [self.collectionView reloadData];
        if (error != nil)
        {
            NSLog(@"Error: %@", error);
            return;
        }
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
    // Code here to support video if enabled
}
}
--end of code to save image

像相机胶卷这样的应用程序的最佳方法是什么,我可以看到超过 6 张图像?也许我将它们保存错误或将错误添加到集合视图中?谢谢。

【问题讨论】:

    标签: memory uiimage uicollectionviewcell


    【解决方案1】:

    方法中缩小图片尺寸

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
             cellForItemAtIndexPath:(NSIndexPath *)indexPath
    

    您可以使用UIImage 可用的类别here

    使用方法

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

    编辑: 1. 包含来自urlhttp://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/的以下文件

    • UIImage+Resize.h、UIImage+Resize.m
    • UIImage+RoundedCorner.h、UIImage+RoundedCorner.m
    • UIImage+Alpha.h,UIImage+Alpha.m

    2.导入UIImage+Resize.h

    3.改变你的方法

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
             cellForItemAtIndexPath:(NSIndexPath *)indexPath
    

    看起来像下面

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"Entra a las celdas");
        static NSString *identificador=@"celdaImagen";
        celdaImagen *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:identificador forIndexPath:indexPath];
        UIImage* image = [UIImage imageWithContentsOfFile:[imagesArray objectAtIndex:indexPath.item]];
    
        NSData *imageData = UIImagePNGRepresentation(image); //png o jpg
        NSLog(@"tamano imagen %i",(imageData.length)/1024);
    
        myCell.imagen.image=[image thumbnailImage:20 // This should the size of the view in collection view. example: myCell width is 20 and height is 20. 
                                transparentBorder:0
                                     cornerRadius:0
                             interpolationQuality:kCGInterpolationMedium];
        return myCell;
    }
    

    希望对你有帮助。

    【讨论】:

    • 您能否更具体地说明我如何使用该方法?我已经尝试过了,我对此有点陌生,但是我注意到我的记忆力在增长并且从未减少,我可以回归“父”控制器,再次加入这个视图,内存不断增加,内存永远不会释放,我做错了什么吗?
    • 哇这实际上对我有很大帮助,但是我可以问你一些与图像无关的事情吗,一旦对象超出范围,ARC 就会删除它,或者当它被收集到垃圾?我在确定何时收集对象时遇到了一些麻烦,因为我仍然可以从前一个视图中看到对象。这段代码到底是做什么的? delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    • 更新每个人都在问为什么会发生这种情况,我发现了设备直接从相机保存图像的方式,它做了一些讨厌的事情,当它解压缩图像时,每次都会出现内存泄漏,内存不是免费的,所以我只是用以前的库重新编译原始大小的图像,一切都很顺利。
    猜你喜欢
    • 2014-04-07
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    相关资源
    最近更新 更多