iOS, непредвиденные результаты при попытке отобразить масштабированное представление с преобразованием с помощью UIGraphicsGetImageFromCurrentImageContext

Я пытаюсь отобразить представление и его содержимое после преобразования с использованием UIGraphicsGetImageFromCurrentImageContext. Несмотря на то, что представление уменьшено, когда я его отображаю, размер изображения правильный, но содержимое отображается в исходном размере (в этом случае они обрезаются, а не соответствуют ожидаемому виду.

введите здесь описание изображения

вот простой пример проекта: http://owolf.net/uploads/StackOverflow/ParentChildTransformTester.zip

Чтобы объяснить дальше: я создаю родительское представление и дочернее представление, добавляю дочернее представление в качестве подпредставления. Затем я преобразую масштаб родительского вида, который также изменяет размер дочернего элемента (как я хочу). Затем я создаю контекст изображения с текущим размером кадра родительского представления и выполняю рендеринг. Код ниже.

//create views
UIView *parentView = [[UIView alloc]initWithFrame:self.view.bounds];
[parentView setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:parentView];

UIView *childView = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
[childView setBackgroundColor:[UIColor redColor]];
[parentView addSubview:childView];

//log parent view size : result is device screen size
NSLog(@"parentView.frame.size, BEFORE tran: %f x %f", parentView.frame.size.width, parentView.frame.size.height);

float scaleFactor = 0.2;
CGAffineTransform trans = CGAffineTransformScale(CGAffineTransformIdentity, scaleFactor, scaleFactor);
parentView.transform = trans;

//log parent view size after transform :  result is device screen size * 0.2
NSLog(@"parentView.frame.size, AFTER tran: %f x %f", parentView.frame.size.width, parentView.frame.size.height);


//attemt to render and save scaled parent view.
CGSize renderSize = CGSizeMake(parentView.frame.size.width, parentView.frame.size.height);
UIGraphicsBeginImageContext(CGSizeMake(renderSize.width, renderSize.height));

[[parentView layer] renderInContext:UIGraphicsGetCurrentContext()];

UIImage *renderedImage;
renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageWriteToSavedPhotosAlbum(renderedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

person Mr Wolf    schedule 27.02.2013    source источник


Ответы (2)


Вам необходимо применить преобразование к текущей матрице преобразования перед визуализацией слоя:

...
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextConcatCTM(ctx, [[parentView layer] affineTransform]);

[[parentView layer] renderInContext:ctx];
...
person graver    schedule 27.02.2013
comment
Спасибо! Нужно ли сбрасывать текущую матрицу преобразования после рендеринга? - person Mr Wolf; 27.02.2013
comment
Нет, проще всего было бы: CGContextSaveGState, CGContextConcatCTM, визуализировать, CGContextRestoreGState, затем продолжить рисование без преобразования, примененного к текущему CTM. - person graver; 27.02.2013

Это сработало: изменено в соответствии с ответом Гравера выше.

UIGraphicsBeginImageContext(parentView.frame.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextConcatCTM(ctx, [[parentView layer] affineTransform]);
[[parentView layer] renderInContext:UIGraphicsGetCurrentContext()];
renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(renderedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
person Mr Wolf    schedule 27.02.2013