UIImage из фото библиотеки очень большой - PullRequest
0 голосов
/ 05 октября 2010

В моей игре я получаю изображение из библиотеки фотографий iPhone с помощью UIImagePickerController, который возвращает UIImage. Поскольку изображение имеет огромное разрешение (1536x2048), этот UIImage занимает почти 20 Мб памяти. Чтобы решить эту проблему, я значительно уменьшил изображение, прежде чем использовать его для создания спрайта, и это помогает уменьшить объем памяти. Тем не менее, перед изменением размера изображения наступает короткий момент, когда объем использования памяти действительно увеличивается, и я беспокоюсь, что это может привести к сбоям в ситуациях нехватки памяти (хотя я не получаю предупреждений о нехватке памяти). У кого-нибудь есть идеи, как бороться с этим сценарием?

Спасибо!

Ответы [ 2 ]

1 голос
/ 05 октября 2010

Взгляните на это, оно говорит об изменении размера изображений и так далее:

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

Отличный учебник по FAQ по uiimagepickercontroller, uiimage, memory и многим другим.

EDIT:

Предупреждения в памяти чрезвычайно распространены при работе с UIImagePickerController. Это особенно актуально при использовании камеры. Помните, что, хотя размер файла JPG или PNG на диске может составлять всего несколько МБ, растровое изображение без сжатия в памяти, используемое для рисования изображения, использует значительно больше.

Нет ничего, что вы делаете неправильно, но некоторые улучшения могут быть сделаны:

Вместо того, чтобы хранить байты образа в Core Data, почему бы не записать образ на диск и не сохранить путь к файлу в вашей базе данных?

и если вы используете авто-выпуск, а не так много автоматически выпущенных изображений, можете ли вы найти способ напрямую управлять их жизненным циклом и выпускать их раньше?

Лучше всего записать изображения на диск как можно скорее после обработки и освободить используемую ими память. Затем сохраните их местоположение с использованием 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

0 голосов
/ 05 октября 2010

Я могу точно подтвердить, что вы говорите: UIImagePicker для довольно короткого момента своего существования является огромной оперативной памятью.

Все, что я могу вам сказать, это очистить как можно больше памятина вашем пути. Мне удалось свести к минимуму сбои, вытащив каждое другое изображение, которое у меня есть в памяти, и загрузив его обратно после того, как я поймал и изменил размер UIImage, который я возвратил из сборщика.

Единственное РЕАЛЬНОЕ решение, которое янашел, чтобы получить себе iPhone 4. Он имеет достаточно памяти, чтобы справиться.Мой бедный старый 3G было очень легко раздавить с помощью UIImagePicker.

...