2012-05-11 3 views
3

Основная идея того, что мы пытаемся сделать, это то, что у нас большой UIImage, и мы хотим нарезать его на несколько частей. Пользователь функции может проходить в количестве строк и количества столбцов, и изображение будет обрезано соответственно (т. Е. 3 строки и 3 столбца разрезают изображение на 9 частей). Проблема в том, что у нас возникают проблемы с производительностью при попытке выполнить это с помощью CoreGraphics. Самая большая сетка, в которой мы нуждаемся, составляет 5х5, и для завершения операции требуется несколько секунд (которая регистрируется как время ожидания для пользователя). Это, конечно, далеко не оптимально.Проблемы с производительностью при обрезке UIImage (CoreGraphics, iOS)

Мой коллега и я провели некоторое время на этом, и безуспешно искали в Интернете ответы. Ни один из нас не очень опытен с Core Graphics, поэтому я надеюсь, что в коде есть какая-то глупая ошибка, которая поможет исправить наши проблемы. Осталось вам, пользователям SO, помочь нам понять это!

Мы использовали учебник по адресу http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/ для внесения изменений в наш код.

Функция ниже:

-(void) getImagesFromImage:(UIImage*)image withRow:(NSInteger)rows withColumn:(NSInteger)columns 
{ 
    CGSize imageSize = image.size; 
    CGFloat xPos = 0.0; 
    CGFloat yPos = 0.0; 
    CGFloat width = imageSize.width/columns; 
    CGFloat height = imageSize.height/rows; 

    int imageCounter = 0; 

    //create a context to do our clipping in 
    UIGraphicsBeginImageContext(CGSizeMake(width, height)); 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

    CGRect clippedRect = CGRectMake(0, 0, width, height); 
    CGContextClipToRect(currentContext, clippedRect); 

    for(int i = 0; i < rows; i++) 
    { 
     xPos = 0.0; 
     for(int j = 0; j < columns; j++) 
     { 
      //create a rect with the size we want to crop the image to 
      //the X and Y here are zero so we start at the beginning of our 
      //newly created context 
      CGRect rect = CGRectMake(xPos, yPos, width, height); 

      //create a rect equivalent to the full size of the image 
      //offset the rect by the X and Y we want to start the crop 
      //from in order to cut off anything before them 
      CGRect drawRect = CGRectMake(rect.origin.x * -1, 
            rect.origin.y * -1, 
            image.size.width, 
            image.size.height); 

      //draw the image to our clipped context using our offset rect 
      CGContextDrawImage(currentContext, drawRect, image.CGImage); 

      //pull the image from our cropped context 
      UIImage* croppedImg = UIGraphicsGetImageFromCurrentImageContext(); 


      //PuzzlePiece is a UIView subclass 
      PuzzlePiece* newPP = [[PuzzlePiece alloc] initWithImageAndFrameAndID:croppedImg :rect :imageCounter]; 
      [slicedImages addObject:newPP]; 

      imageCounter++; 
      xPos += (width); 
     } 
     yPos += (height); 
    } 
    //pop the context to get back to the default 
    UIGraphicsEndImageContext(); 
} 

ANY совет высоко оценили !!

+0

Сохраняете ли вы изображения где-нибудь или показываете их только пользователю в 5x5 разных вариантах экрана? Если вы только показываете их, вероятно, будет более эффективно устанавливать все изображение в каждом представлении (это все еще только одно изображение в памяти), а затем смещать его для каждого UIImageView, чтобы в каждом представлении отображалась только правильная часть. –

+0

@ DavidRönnqvist Мы показываем их, а не сохраняем их. Ваш ответ звучит как гораздо более эффективное решение! Я никогда не пробовал компенсировать UIImage в UIImageView - я использовал initWithImage и setImage только для установки самого изображения, а потом не играл с ним. Как ты это делаешь? Хотя я полагаю, что я мог бы использовать обычный UIView с clipToBounds = true, добавить UIImageView в качестве подзаголовка и компенсировать это UIImageView любой суммой, необходимой? – WendiKidd

+0

@ DavidRönnqvist Мое изменение того, что вы предложили - с UIView/clipsToBounds/UIImageView в качестве подвид - работало как шарм! Если вы опубликуете ответ, подробно рассказывающий о том, что вместе с вашим первоначальным предложением, я был бы рад принять его :) Большое спасибо - это так меня прослушивало! – WendiKidd

ответ

0

originalImageView - это изображение IBOutlet ImageView. Это изображение будет обрезано.

#import <QuartzCore/QuartzCore.h> 

QuartzCore необходим для белой границы вокруг каждого ломтика для лучшего понимания.

-(UIImage*)getCropImage:(CGRect)cropRect 
{ 
CGImageRef image = CGImageCreateWithImageInRect([originalImageView.image CGImage],cropRect); 
UIImage *cropedImage = [UIImage imageWithCGImage:image]; 
CGImageRelease(image); 
return cropedImage; 
} 

-(void)prepareSlices:(uint)row:(uint)col 
{ 
float flagX = originalImageView.image.size.width/originalImageView.frame.size.width; 
float flagY = originalImageView.image.size.height/originalImageView.frame.size.height; 

float _width = originalImageView.frame.size.width/col; 
float _height = originalImageView.frame.size.height/row; 

float _posX = 0.0; 
float _posY = 0.0; 

for (int i = 1; i <= row * col; i++) { 

    UIImageView *croppedImageVeiw = [[UIImageView alloc] initWithFrame:CGRectMake(_posX, _posY, _width, _height)]; 
    UIImage *img = [self getCropImage:CGRectMake(_posX * flagX,_posY * flagY, _width * flagX, _height * flagY)]; 
    croppedImageVeiw.image = img; 

    croppedImageVeiw.layer.borderColor = [[UIColor whiteColor] CGColor]; 
    croppedImageVeiw.layer.borderWidth = 1.0f; 

    [self.view addSubview:croppedImageVeiw]; 
    [croppedImageVeiw release]; 

    _posX += _width; 

    if (i % col == 0) { 
     _posX = 0; 
     _posY += _height; 
    } 

} 

originalImageView.alpha = 0.0; 

} 

originalImageView.alpha = 0.0; вы больше не увидите оригиналImageView.

Зов это следующим образом:

[self prepareSlices:4 :4]; 

Он должен сделать 16 ломтиков addSubView на self.view. У нас есть приложение для головоломки. Это рабочий код оттуда.

+0

У меня все работает с комментарием Дэвида Рёнквиста выше, но похоже, что это сработает. Если у меня появится шанс вернуться и поиграть с этим кодом, я попробую. Благодаря! – WendiKidd

Смежные вопросы