在我的应用程序中,用户从一个UIImage开始。根据用户输入,该应用程序会围绕图像的特定部分创建一个剪切路径。然后,我希望能够将剪辑版本保存到应用程序的文档目录中,以便以后可以显示。
据我所知,所有这些都很顺利,除了稍后显示剪辑后的图像。只要我尝试显示图像(通过添加自定义视图),我就会得到各种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);
}
几乎我所做的一切上下文和上下文对我来说是完全神奇的。这是我从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:
方法中的单行甚至被调用之前(我已经尝试在该行上放置一个断点,但应用程序首先崩溃)。
我知道这是很多代码,但那是因为我甚至不知道从哪里开始调试这一个。除了解决我的特殊问题,我希望有一个更广泛地解决我使用/误用上下文的答案。
尝试为您的绘图创建一个新的上下文,然后在完成绘图时结束它。这可能会修复您的上下文错误。
CGSize mySize = CGSizeMake(rect.size.width,rect.size.height);
UIGraphicsBeginImageContext(mySize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// The rest of your code goes here...
UIGraphicsEndImageContext();