【问题标题】:UIImage from photo library very large来自照片库的 UIImage 非常大
【发布时间】:2011-04-21 11:51:19
【问题描述】:

在我的游戏中,我使用 UIImagePickerController 从 iPhone 的照片库中抓取图像,该控制器返回一个 UIImage。因为图像是一个巨大的分辨率(1536x2048),这个 UIImage 占用了将近 20mb 的内存。为了解决这个问题,我在使用它生成精灵之前显着缩小了图像,这可以减少内存占用。但是,在调整图像大小之前有一个短暂的时刻,我的内存使用率真的很高,我担心这可能会在内存不足的情况下导致崩溃(尽管我没有收到任何内存不足的警告)。有人对如何处理这种情况有任何想法吗?

谢谢!

【问题讨论】:

    标签: iphone memory uikit uiimage uiimagepickercontroller


    【解决方案1】:

    看看这个它谈到了正确调整图像大小等等:

    https://stackoverflow.com/questions/1282830/uiimagepickercontroller-uiimage-memory-and-more

    这是关于 uiimagepickercontroller、uiimage、内存等常见问题解答的精彩教程。

    编辑:

    在处理 UIImagePickerController 时,内存警告非常常见。在使用相机时尤其如此。请记住,虽然磁盘上的 JPG 或 PNG 可能只有几 MB,但用于绘制图像的未压缩内存位图占用的空间要大得多。

    没有什么是你做错了,但可以做一些改进:

    与其将图像字节存储在 Core Data 中,为什么不将图像写入磁盘并将文件的路径存储在数据库中?

    如果你使用自动发布,而不是使用这么多自动发布的图像,你能找到一种方法来直接管理它们的生命周期并更快地发布它们吗?

    您最好的选择可能是在处理后尽快将图像写入磁盘并释放它们正在使用的内存。然后使用 Core Data 而不是原始数据存储他们的位置。

    甚至删除所有加载的图像,存储到磁盘,加载新图像,然后存储到磁盘,然后通过路径加载图像。类似的东西。

    你可以像这样修改一些代码: Getting crash after picking images from UIImagePickerController (Related to memory leak?)

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
    
        [self dismissModalViewControllerAnimated:YES];
    
        if (object.imagePath != nil) {
            [self deleteImages];
        }
        dispatch_queue_t image_queue;
        image_queue = dispatch_queue_create("com.gordonfontenot.app", NULL);
    
        dispatch_async(image_queue, ^{
    
            NSDate *now = [NSDate date];
    
            NSDateFormatter *f = [[NSDateFormatter alloc] init];
            [f setDateFormat:@"yyyyMMDDHHmmss"];
    
            NSString *imageName = [NSString stringWithFormat:@"Image-%@-%i", [f stringFromDate:now], arc4random() % 100];
            NSString *thumbName = [NSString stringWithFormat:@"%@-thumb", imageName];
    
            [f release];
    
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentsDirectory = [paths objectAtIndex:0];
    
            NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:imageName];
            NSString *thumbPath = [documentsDirectory stringByAppendingPathComponent:thumbName];
    
            NSData *thumbImageData = UIImagePNGRepresentation([UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerEditedImage"] toSize:CGSizeMake(120, 120)]);
            [thumbImageData writeToFile:thumbPath atomically:NO];
            dispatch_async(dispatch_get_main_queue(), ^{
                object.thumbPath = thumbPath;
                [self setupImageButton];
                imageButton.enabled = NO;
                [self setupChooseImageButton];
            });
            NSData *fullImageData = UIImagePNGRepresentation([UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerOriginalImage"] toSize:CGSizeMake(800, 600)]);
            [fullImageData writeToFile:fullPath atomically:NO];
    
            dispatch_async(dispatch_get_main_queue(), ^{
                imageButton.enabled = YES;
                object.imagePath = fullPath;
            });
    
            if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
                UIImageWriteToSavedPhotosAlbum([info objectForKey:@"UIImagePickerControllerOriginalImage"], self, nil, nil);
            }
    
        });
        dispatch_release(image_queue);
    }
    

    希望您有足够的信息可以从这里继续。

    PK

    【讨论】:

    • 是的,这是我从中获取调整大小代码的确切教程。它没有提到如何处理内存峰值:(
    • 这是一个很好的教程,但仍然有一段时间,返回的图像非常庞大,除了将易碎的盘子从桌子上移开之外别无他法。
    • 好的,我在进行了一些研究并从不同的问题中选择了一些选项后更新了帖子,并找到了你现在可以做的事情,因为你不能按照你想要的方式直接做任何其他事情。
    【解决方案2】:

    我可以确切地确认您在说什么:UIImagePicker 在其生命周期中相当短暂的一段时间内是一个巨大的 RAM 猪。

    我能告诉你的就是在进入的过程中尽可能多地清除内存。我设法通过丢弃内存中的所有其他图像并在捕获并调整 UIImage 的大小后重新加载它来最大限度地减少崩溃。 m 从 Picker 中返回。

    我找到的唯一真正的解决方案是给自己买一部 iPhone 4。它有足够的内存来应付。用 UIImagePicker 很容易把我那可怜的老 3G 压垮。

    【讨论】:

    • 买一部 iphone 4。不错 :D 我可能需要给我买一部。
    • 你知道这是 UIImagePicker 本身的问题还是直接由于图像的大小?
    • @stefan_g,这是 UIImagePicker 正在加载的图像的功能,但如果它愿意,它无法阻止它加载巨大的图像。从相机中提取图像也是一项繁重的工作......最好的策略就是尽可能地避开它。
    猜你喜欢
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多