裁剪UIImage(CoreGraphics,iOS)时的性能问题

裁剪UIImage(CoreGraphics,iOS)时的性能问题,ios,uikit,uiimage,core-graphics,crop,Ios,Uikit,Uiimage,Core Graphics,Crop,我们尝试做的基本想法是,我们有一个大的UIImage,我们想把它切成几块。该函数的用户可以传入若干行和若干列,图像将被相应地裁剪(即,3行和3列将图像切成9块)。问题是,我们在尝试使用CoreGraphics实现这一点时遇到了性能问题。我们需要的最大网格是5x5,操作需要几秒钟才能完成(用户注册为滞后时间)。这当然远远不是最佳的 我的同事和我在这方面花了很长时间,在网上搜索答案都没有成功。我们两人对核心图形都不是很有经验,所以我希望代码中有一些愚蠢的错误可以解决我们的问题。这是留给你的,所以用户

我们尝试做的基本想法是,我们有一个大的UIImage,我们想把它切成几块。该函数的用户可以传入若干行和若干列,图像将被相应地裁剪(即,3行和3列将图像切成9块)。问题是,我们在尝试使用CoreGraphics实现这一点时遇到了性能问题。我们需要的最大网格是5x5,操作需要几秒钟才能完成(用户注册为滞后时间)。这当然远远不是最佳的

我的同事和我在这方面花了很长时间,在网上搜索答案都没有成功。我们两人对核心图形都不是很有经验,所以我希望代码中有一些愚蠢的错误可以解决我们的问题。这是留给你的,所以用户,请帮助我们解决它

我们在上使用了教程来修改代码

功能如下:

-(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();
}
-(void)getImagesFromImage:(UIImage*)图像带行:(NSInteger)行带列:(NSInteger)列
{
CGSize imageSize=image.size;
CGFloat xPos=0.0;
cgpos=0.0;
CGFloat width=imageSize.width/列;
CGFloat height=imageSize.height/行;
int-imageCounter=0;
//创建一个上下文来进行剪辑
UIGraphicsBeginImageContext(CGSizeMake(宽度、高度));
CGContextRef currentContext=UIGraphicsGetCurrentContext();
CGRect CLIPEDRECT=CGRectMake(0,0,宽度,高度);
cgContextCliptRect(currentContext,clippedRect);
对于(int i=0;i

非常感谢您的建议

originalImageView是一个IBOutlet图像视图。此图像将被裁剪

#import <QuartzCore/QuartzCore.h>

它应该在self.view上创建16个子视图。我们有一个益智应用程序。这是那里的工作代码。

您是将图像保存在某个位置,还是仅在屏幕上的5x5个不同视图中向用户显示?如果只显示它们,则在每个视图中设置整个图像(内存中仍然只有一个图像),然后在每个UIImageView中对其进行偏移,以便在每个视图中只显示正确的部分可能会更有效。@DavidRönnqvist我们只显示它们,而不是保存它们。你的答案听起来更有效!我从未尝试过在UIImageView中偏移UIImage——我只使用initWithImage和setImage来设置图像本身,之后从未使用过它。你是怎么做到的?尽管我认为--我可以使用clipsToBounds=true的常规UIView,添加一个UIImageView作为子视图,并将该UIImageView偏移任何必要的量?@DavidRönnqvist我对您建议的更改--使用UIView/clipsToBounds/UIImageView作为子视图--效果非常好!如果你在最初的建议中附上一个详细的答案,我很乐意接受:)非常感谢——这一直困扰着我@DavidRönnqvist-我不确定你的内存中只有一份图像。这些视图中的每一个都应该在幕后保存一个单独的未压缩版本的图像(每像素4字节),如果您在内存监视器工具中查看应用程序的真实大小,我想您会看到这一点。@BradLarson-Hmm,在这种情况下,这肯定不是一个内存有效的解决方案。你有什么想法,我们可以做一些既不占用大量内存又能高效运行的事情吗?谢谢我用大卫·伦克维斯特(David Rönnqvist)上面的评论做了所有的工作,但这似乎也会起作用。如果我有机会回去玩那个代码,我会试试这个。谢谢
-(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;

}
[self prepareSlices:4 :4];