Применение трансформированного слоя изображения к renderInContext:

Задний план

Я использую пример поваренной книги Эрики Садун из Chapter 8, Example 14 — Resize and Rotate, чтобы явно изменить размер и повернуть UIImageView.

Посмотреть иерархию

1.) полосатый фон.

2.) интерактивный вид, который можно изменять и вращать.

3.) наложенное изображение с прозрачной частью. этот вид начинает свою ось Y с 128 и имеет размер 768x768.

4.) выше и ниже 3, есть 2 вида 128 в высоту.

******См. пример фото ниже****

Проблема

В настоящее время я могу сохранить весь слой вида в библиотеке фотографий, используя [[[self view] layer] renderInContext:, и преобразования #2 верны. Однако мне нужен способ сохранить кадр 768 x 768 (светло-зеленый на примере фотографии), содержащий только №2 и №3. , включая преобразования #2. Если я использую [[#2 layer] renderInContext:, я получаю исходное изображение и никаких преобразований. (см. # справку на снимке экрана ниже.

Код

CGSize deviceSpec;
if ( IDIOM == IPAD ) { deviceSpec =CGSizeMake(768,768); } else { deviceSpec =CGSizeMake(320,480); }
if (  scale > 1.5  ) {
    UIGraphicsBeginImageContextWithOptions(deviceSpec, NO, scale);
} else {
    UIGraphicsBeginImageContext( deviceSpec );
}        

    CGContextRef ctx = UIGraphicsGetCurrentContext();      

    [[stripedBg layer] renderInContext:ctx];  //#1    

        CGContextSaveGState(ctx);

            CGContextConcatCTM(ctx, [[interactiveImage layer] affineTransform]);

            //CGContextTranslateCTM(ctx, interactiveImage.frame.origin.x,interactiveImage.frame.origin.y-128);

            [[interactiveImage layer] renderInContext:ctx]; // #2

        CGContextRestoreGState(ctx);

    [[overlayImage layer] renderInContext:ctx]; // #3

    UIImage * draft = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

Пример фото

Мне нужна только часть изображения, обведенная LIME GREEN, при сохранении преобразований, сделанных пользователем.

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


person WrightsCS    schedule 07.09.2011    source источник


Ответы (1)


Если я вас правильно понял, проблема в том, что вы хотите визуализировать только слой № 2, но слой № 2 имеет преобразования, которые не сохраняются при рендеринге только этого слоя? Вы можете применить эти преобразования к CTM графического контекста (текущая матрица преобразования) перед визуализацией слоя в этом контексте. Что-то вроде этого должно работать:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextConcatCTM(ctx, [layer2 affineTransform]);
[layer2 renderInContext:ctx];
CGContextRestoreGState(ctx);

Обратите внимание, что вызовы CGContextSaveGState() и CGContextRestoreGState() необходимы только в том случае, если вы хотите добавить больше материала в контекст после того, как нарисуете слой. Вы можете опустить их, если слой — это все, что вам нужно.

person Lily Ballard    schedule 07.09.2011
comment
Мне нужно иметь возможность включать только # 2 и # 3, которые являются двумя разными UIImageView. - person WrightsCS; 08.09.2011
comment
@WrightsCS: №3 — это не подвид №2? Если нет, вы можете просто визуализировать #3 в контексте после того, как вы визуализировали #2. Однако вам придется применить свое собственное аффинное преобразование, чтобы установить происхождение контекста, как и ожидалось для каждого слоя. - person Lily Ballard; 08.09.2011
comment
каждый слой является подвидом основного вида, ни один из них не является подвидом другого. - person WrightsCS; 08.09.2011
comment
@WrightsCS: Вы можете снова использовать CTM. Просто используйте CGContextTranslateCTM(view.frame.origin.x, view.frame.origin.y) для настройки CTM перед рисованием вида (в случае слоя 2 примените его affineTransform к CTM после выполнения перевода). Затем вы можете нарисовать слой № 2, а затем слой № 3 (каждый со своим переводом). Обратите внимание, что вы захотите сохранить и восстановить GState вокруг переводов/рендеринга. - person Lily Ballard; 08.09.2011
comment
Итак, как я буду вычислять x и y для # 2, если он трансформируется, потому что они должны меняться при каждом повороте/изменении размера, правильно ли я понимаю? - person WrightsCS; 08.09.2011
comment
@WrightsCS: рамка представления выражается в системе координат его родителя. Они, так сказать, не трансформированы. Поэтому, если вы переведете CTM по происхождению представления, а затем соедините собственное преобразование представления, рисунок должен быть правильным. Конечно, в вашем случае вы, вероятно, захотите вычесть 128 из координаты Y обоих ваших представлений, потому что я предполагаю, что размер вашего контекста соответствует только зеленой части. Вы можете добиться этого, просто сделав сдвиг -128 по оси Y, прежде чем начать обработку своих представлений. - person Lily Ballard; 08.09.2011
comment
@KevinBallard, не могли бы вы взглянуть на этот вопрос, бедняге нужна помощь: stackoverflow.com - person Abduliam Rehmanius; 28.07.2013
comment
Вы спасли мой день! Мне пришлось сделать UIImage из UIView, который масштабируется с помощью CGAffineTransformMakeScale. Добавление CGContextConcatCTM(ctx, [layer2 affineTransform]); делает свое дело :) - person Josip B.; 29.11.2013
comment
Не поддерживает трансформацию всех слоев, как m34 (перспектива) - person jjxtra; 17.05.2014