Performance issues when cropping UIImage (CoreGraphics, iOS)

ぐ巨炮叔叔 提交于 2019-12-10 21:14:27

问题


The basic idea of what we are trying to do is that we have a large UIImage, and we want to slice it into several pieces. The user of the function can pass in a number of rows and number of columns, and the image will be cropped accordingly (ie. 3 rows and 3 columns slices the image into 9 pieces). The problem is, we're having performance issues when trying to accomplish this with CoreGraphics. The largest grid we require is 5x5, and it takes several seconds for the operation to complete (which registeres as lagtime to the user.) This is of course far from optimal.

My colleague and I have spent quite a while on this, and have searched the web for answers unsuccessfully. Neither of us are extremely experienced with Core Graphics, so I'm hoping there's some silly mistake in the code that will fix our problems. It's left to you, SO users, to please help us figure it out!

We used the tutorial at http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/ to base revisions of our code on.

The function below:

-(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 advice greatly appreciated!!


回答1:


originalImageView is an IBOutlet ImageView. This image will be cropped.

#import <QuartzCore/QuartzCore.h>

QuartzCore is needed for the white border around each slice for better understanding.

-(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; you won't see the originalImageView any more.

Call it like this:

[self prepareSlices:4 :4];

It should make 16 slices addSubView on self.view. We have a puzzle app. This is working code from there.



来源:https://stackoverflow.com/questions/10558035/performance-issues-when-cropping-uiimage-coregraphics-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!