照片库中的 UIImage 非常大

发布于 2024-09-26 13:18:45 字数 265 浏览 4 评论 0原文

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

谢谢!

In my game I'm grabbing an image from the iPhone's photo library using the UIImagePickerController, which returns a UIImage. Because the image is a huge resolution (1536x2048), this UIImage takes up almost 20mb in memory. To resolve this, I shrink the image significantly before using it to generate a sprite and this works in reducing the memory footprint. However, there is a brief moment before the image is resized that my memory usage spikes really high, and I'm worried this could cause crashes in low memory situations (although I don't get any low memory warnings). Anyone have any ideas on how to deal with this scenario?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瑾兮 2024-10-03 13:18:45

看看这个,它讨论了如何正确调整图像大小等:

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

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

编辑:

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

您不一定做错了什么,但可以进行一些改进:

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

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

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

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

你可以像这样修改一些代码:
从 UIImagePickerController 选取图像后崩溃(与内存泄漏有关) ?)

- (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

Have a look at this it talks about resizing images and so on correctly:

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

Its a great tutorial on FAQ on uiimagepickercontroller, uiimage, memory and more.

EDIT:

Memory warnings are extremely common when dealing with the UIImagePickerController. This is especially true when using the camera. Keep in mind that while a JPG or PNG on disk may only amount to a few MB, the uncompressed in memory bitmap used to draw the image uses considerably more.

There's nothing that you're doing wrong necessarily, but some improvements can be made:

Rather than storing the image bytes in Core Data, why not write the image to disk and store the path to the file in your database?

and if you are using autorelease, rather than using so many autoreleased images, can you find a way to manage their lifecycle directly and release them sooner?

Your best bet may be to write the images to disk as soon after processing as possible and free up the memory they're using. Then store their location using Core Data rather than the raw data.

Or even remove all images loaded, store to disk, load new image, then store to disk, then load images via the path. something like that.

you can some modified code like so:
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);
}

Hopefully you have enough information to go on from here.

PK

╰ゝ天使的微笑 2024-10-03 13:18:45

我可以准确地证实你所说的:UIImagePicker 在其生命周期中相当短暂的一段时间内是一个巨大的内存消耗者。

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

我找到的唯一真正的解决方案是给自己买一部 iPhone 4。它有足够的内存来应对。我可怜的旧 3G 很容易被 UIImagePicker 压坏。

I can confirm exactly what you're saying: UIImagePicker is, for a fairly brief moment of its lifetime, a massive RAM hog.

All I can tell you is to clear as much memory as you can on your way in. I managed to minimize crashing by ditching every other image I have in memory and loading it back in after I catch and resize the UIImage I'm returned from the Picker.

The only REAL solution I found was to get myself an iPhone 4. It has enough memory to cope. My poor old 3G was very easy to crush with UIImagePicker.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文