开发者

UIImage from photo library very large

开发者 https://www.devze.com 2023-01-19 00:40 出处:网络
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

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 mem开发者_如何学Goory situations (although I don't get any low memory warnings). Anyone have any ideas on how to deal with this scenario?

Thanks!


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消