将剪切路径添加到UIImage,将剪辑的版本保存到Documents文件夹,然后显示它

时间:2011-11-17 22:39:39

标签: ios cocoa-touch cgcontext graphicscontext

在我的应用中,用户开始使用UIImage。根据用户输入,应用程序围绕图像的某个部分创建剪切路径。然后,我希望能够将该剪辑版本保存到应用程序的Documents目录中,以便以后显示。

据我所知,所有这些都很顺利除了以后显示剪辑的图像。只要我尝试显示图片(通过添加自定义视图),我就会收到各种invalid context错误以及message sent to deallocated instance错误。虽然我不确定是什么导致最后一个,但我最关心的是invalid context,因为图形上下文的概念并不是我所熟悉的。

以下是确切的错误:

<Error>: CGBitmapContextSetData: invalid context 0x4b997b0
<Error>: CGContextGetBaseCTM: invalid context 0x4b997b0
<Error>: CGContextConcatCTM: invalid context 0x4b997b0
<Error>: CGContextSetBaseCTM: invalid context 0x4b997b0
<Error>: CGContextSetFillColorSpace: invalid context 0x4b997b0
<Error>: CGContextSetStrokeColorSpace: invalid context 0x4b997b0
*** -[Not A Type retain]: message sent to deallocated instance 0x4b997b0

此时,我将发布创建剪切路径的代码,然后尝试使用剪切的图像作为新图像保存上下文的代码,最后是尝试显示图像的代码再次。正如我上面所说,在我尝试再次显示图像之前,我没有收到错误。

创建剪切路径:

- (void)drawRect:(CGRect)rect
{   
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);

    //Create clippingPath
    UIBezierPath *edgePath = [[UIBezierPath alloc] init];
    NSValue *firstPt = [edgePts objectAtIndex:0];

    [edgePath moveToPoint:CGPointMake([firstPt CGPointValue].x / scaleRatio, [firstPt CGPointValue].y / scaleRatio + 20)];
    [edgePts removeObject:firstPt];

    for (NSValue *pt in edgePts) {
        [edgePath addLineToPoint:CGPointMake([pt CGPointValue].x / scaleRatio, [pt CGPointValue].y / scaleRatio + 20)];
    }

    clippingPath = edgePath;

    [clippingPath addClip];

    [img drawAtPoint:CGPointMake(0, 20)];

    clippedContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(clippedContext);

    CGContextRestoreGState(ctx);
}

我正在使用上下文和contextRef做的所有事情对我来说都是完全神奇的。这是我从SO的其他帖子拼凑而成的东西,基本上不知道它在做什么。令人震惊的是我最终遇到了所有这些背景错误,是吧? ;)

保存图像,然后立即尝试显示图像(错误发生在最后一行):

- (void)saveCutout
{
    CGImageRef clippedImageRef = CGBitmapContextCreateImage(imageView.clippedContext);
    CGContextRelease(imageView.clippedContext);
    UIImage *clippedImage = [UIImage imageWithCGImage:clippedImageRef];
    CGImageRelease(clippedImageRef);

    NSData *imgData = UIImagePNGRepresentation(clippedImage);
    NSString *imgPath = [NSString stringWithFormat:@"%@/1.png", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
    [imgData writeToFile:imgPath atomically:NO];

    //just testing to make sure it worked. first I hide the other two visible views
    imageView.hidden = YES;
    includedFrameView.hidden = YES;

    UIImage *newImg = [[UIImage imageWithContentsOfFile:imgPath] retain];
    ShowImage *imgView = [[ShowImage alloc] initWithFrame:CGRectMake(0, 0, 320, 480) andImage:newImg];

    [self.view addSubview:imgView]; //ERRORS occur once this line runs

}

ShowImage类是一个简单的UIView子类。所有这一切都是使用指定的UIImage进行初始化,并且它的drawRect:方法如下:

- (void)drawRect:(CGRect)rect
{
    [img drawAtPoint:CGPointMake(0, 20)];
}

值得注意的是,甚至在上面的drawRect:方法中的单行甚至被调用之前就会发生错误(我已尝试在该行上设置断点但应用程序首先崩溃)。

我知道这是很多代码,但那是因为我甚至不知道从哪里开始调试这个代码。除了解决我的特定问题外,我还喜欢一个更广泛地解决我使用/误用语境的答案。

1 个答案:

答案 0 :(得分:0)

尝试为绘图创建新的上下文,然后在完成绘图后结束它。这可能会修复您的上下文错误。

CGSize mySize = CGSizeMake(rect.size.width,rect.size.height);
UIGraphicsBeginImageContext(mySize);
CGContextRef ctx = UIGraphicsGetCurrentContext();

// The rest of your code goes here...

UIGraphicsEndImageContext();