В моем приложении пользователь начинает с 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);
}
Практически все, что я делаю с контекстами и contextRefs выше, является для меня полной магией. Это то, что я собрал из других постов здесь, в 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:
методе выше даже вызывается (я пытался установить точку останова на этой строке, но сначала приложение вылетает).
Я знаю, что кода много, но это потому, что я даже не знаю, с чего начать отладку этого. Наряду с решением моей конкретной проблемы, я хотел бы получить ответ, который более широко рассматривает мое использование / неправильное использование контекстов.