Добавление обтравочного контура в UIImage, сохранение обрезанной версии в папке "Документы", а затем ее отображение
В моем приложении пользователь начинает с 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:
вышеупомянутый метод даже вызывается (я пытался поставить точку останова на этой строке, но сначала приложение вылетает).
Я знаю, что кода много, но это потому, что я даже не знаю, с чего начать отладку этого. Наряду с решением моей конкретной проблемы, я хотел бы получить ответ, который более широко рассматривает мое использование / неправильное использование контекстов.
1 ответ
Попробуйте создать новый контекст для вашего рисунка, а затем закончите его, когда закончите рисовать. Это может исправить ваши контекстные ошибки.
CGSize mySize = CGSizeMake(rect.size.width,rect.size.height);
UIGraphicsBeginImageContext(mySize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// The rest of your code goes here...
UIGraphicsEndImageContext();