Приложение для iPhone с несколькими операциями с изображениями - PullRequest
3 голосов
/ 25 июня 2009

Я новичок в разработке приложений для iPhone, поэтому, скорее всего, я делаю что-то не так.

По сути, я загружаю кучу изображений из Интернета, а затем обрезаю их. Мне удалось найти примеры загрузки изображений асинхронно и добавления их в представления. Мне удалось сделать это, добавив изображение с NSData через NSOperation, которое было добавлено в NSOperationQueue.

Затем, поскольку мне приходилось делать большие пальцы фиксированного размера, мне нужен был способ обрезать эти изображения, поэтому я нашел в сети сценарий, который в основном использует UIGraphicsBeginImageContext(), UIGraphicsGetImageFromCurrentImageContext() и UIGraphicsEndImageContext() для рисования обрезанного изображение вместе с неважными расчетами размера.

Дело в том, что метод работает, но, поскольку он генерирует около 20 таких изображений, он случайным образом падает после создания нескольких из них, а иногда и после того, как я закрываю и заново открываю приложение еще один или два раза.

Что мне делать в этих случаях? Я также пытался заставить эти методы работать асинхронно с NSOperations и NSOperationQueue, но безуспешно.

Если код обрезки более актуален, чем я думаю, вот он:

UIGraphicsBeginImageContext(CGSizeMake(50, 50));
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = CGPointMake(0.0,0.0); //this is actually generated
                                             // based on the sourceImage size
thumbnailRect.size.width  = 50;
thumbnailRect.size.height = 50;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();

Спасибо!

Ответы [ 3 ]

5 голосов
/ 25 июня 2009

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

    // Draw the image into a pixelsWide x pixelsHigh bitmap and use that bitmap to 
// create a new UIImage 
- (UIImage *) createImage: (CGImageRef) image width: (int) pixelWidth height: (int) pixelHeight
{ 
    // Set the size of the output image 
    CGRect aRect = CGRectMake(0.0f, 0.0f, pixelWidth, pixelHeight); 
    // Create a bitmap context to store the new thumbnail 
    CGContextRef context = MyCreateBitmapContext(pixelWidth, pixelHeight); 
    // Clear the context and draw the image into the rectangle 
    CGContextClearRect(context, aRect); 
    CGContextDrawImage(context, aRect, image); 
    // Return a UIImage populated with the new resized image 
    CGImageRef myRef = CGBitmapContextCreateImage (context); 

    UIImage *img = [UIImage imageWithCGImage:myRef];

    free(CGBitmapContextGetData(context)); 
    CGContextRelease(context);
    CGImageRelease(myRef);

    return img; 
} 


// MyCreateBitmapContext: Source based on Apple Sample Code
CGContextRef MyCreateBitmapContext (int pixelsWide,
                                    int pixelsHigh)
{
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;

    bitmapBytesPerRow   = (pixelsWide * 4);
    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

    colorSpace = CGColorSpaceCreateDeviceRGB();
    bitmapData = malloc( bitmapByteCount );
    if (bitmapData == NULL)
    {
        fprintf (stderr, "Memory not allocated!");
        CGColorSpaceRelease( colorSpace );
        return NULL;
    }
    context = CGBitmapContextCreate (bitmapData,
                                     pixelsWide,
                                     pixelsHigh,
                                     8,
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     kCGImageAlphaPremultipliedLast);
    if (context== NULL)
    {
        free (bitmapData);
        CGColorSpaceRelease( colorSpace );
        fprintf (stderr, "Context not created!");
        return NULL;
    }
    CGColorSpaceRelease( colorSpace );

    return context;
}
2 голосов
/ 05 августа 2009

Ваше приложение аварийно завершает работу, потому что используемые вами вызовы (например, UIGraphicsBeginImageContext) управляют стеком контекста UIKit, который вы можете безопасно выполнять только из основного потока.

Решение unforgiven не будет аварийно завершено при использовании в потоке, поскольку оно не манипулирует стеком контекста.

0 голосов
/ 25 июня 2009

Звучит подозрительно, как сбой памяти. Запустите инструмент «Утечки» и просмотрите общие тенденции памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...