Обрезка CIImage с помощью CICrop не работает должным образом

У меня проблемы с обрезкой изображения. У меня фильтр CICrop не работает должным образом. Если мои CIVector x и y (исходные) равны 0, все работает нормально (изображение обрезается из левого нижнего угла), изображение обрезается по ширине и высоте моего прямоугольника, но если исходные точки CIVector (x и y) не равны 0 в моем обрезанном изображение становится пространством (поскольку фильтр CICrop обрезает нижний левый угол независимо от начала координат (x и y)).

Я обрезаю CIImage прямоугольником, источник:

CIVector *cropRect =[CIVector vectorWithX:150 Y:150 Z: 300 W: 300];

CIFilter *cropFilter = [CIFilter filterWithName:@"CICrop"];   

[cropFilter setValue:myCIImage forKey:@"inputImage"];
[cropFilter setValue:cropRect forKey:@"inputRectangle"];

CIImage *croppedImage = [cropFilter valueForKey:@"outputImage"];

Выходное изображение с CIVector X 150 и Y 150: (для ясности я нарисовал границу)

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

Выходное изображение с CIVector X 0 и Y 0:

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

Исходное изображение:

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

Что я делаю неправильно? Или это надо делать?


person Justin Boo    schedule 07.03.2012    source источник


Ответы (3)


Вы уверены, что выходное изображение соответствует размеру, который вы ожидаете? Как вы рисуете выходное изображение?

Фильтр CICrop не уменьшает размер исходного изображения, он просто скрывает ненужное содержимое.

Чтобы получить желаемый результат, вам, вероятно, нужно просто сделать это:

[image drawAtPoint:NSZeroPoint fromRect:NSMakeRect(150, 150, 300, 300) operation:NSCompositeSourceOver fraction:1.0];

Если вы хотите, чтобы в качестве вывода отображалось фактическое CIImage, а не просто рисование, просто сделайте следующее:

CIImage* croppedImage = [image imageByCroppingToRect:CGRectMake(150, 150, 300, 300)];

//you also need to translate the origin   
CIFilter* transform = [CIFilter filterWithName:@"CIAffineTransform"];
NSAffineTransform* affineTransform = [NSAffineTransform transform];
[affineTransform translateXBy:-150.0 yBy:-150.0];
[transform setValue:affineTransform forKey:@"inputTransform"];
[transform setValue:croppedImage forKey:@"inputImage"];
CIImage* transformedImage = [transform valueForKey:@"outputImage"];
person Rob Keniger    schedule 11.03.2012
comment
Спасибо Роб! Это хорошо для рисования изображения, но как это сделать, если мне нужен обрезанный CIImage, не для рисования, а CIImage. Преобразовать в NSImage lockfocus -> нарисовать изображение -> разблокировать фокус -> преобразовать в CIImage. Хм, я думаю, что это нехорошо, может быть, вы можете мне подсказать, как получить просто полностью обрезанный CIImage? Еще раз большое спасибо за помощь, Роб. +1 - person Justin Boo; 11.03.2012
comment
Я добавил в свой ответ пример метода imageByCroppingToRect:, который позволит достичь того, чего вы хотите. - person Rob Keniger; 12.03.2012
comment
Хм.. это не работает для меня, та же проблема. Посмотрите на мой вопрос, я добавил код обновления внизу. Спасибо за терпение, Роб. - person Justin Boo; 12.03.2012
comment
На самом деле изображение правильное, просто extent полученного изображения равно {150,150,300,300} вместо {0,0,300,300}. Я добавил преобразование в свой ответ, которое исправляет это. Я протестировал его здесь, и, похоже, он работает нормально. - person Rob Keniger; 12.03.2012
comment
Ты прав Роб. Большое спасибо, теперь все работает нормально. - person Justin Boo; 12.03.2012
comment
@RobKeniger С точки зрения эффективности, должны ли мы использовать фильтр Affine Transform или CICrop? - person Roi Mulia; 30.08.2017
comment
@RoiMulia они делают разные вещи, но ни один из них не повлияет на производительность каким-либо заметным образом. - person Rob Keniger; 31.08.2017
comment
@RobKeniger Спасибо за ответ. Я занимаюсь исследованием AVFoundation. В частности, на AVMutableComposition и т. д.». Окончательные результаты я отправлю инженеру Apple, который должен подтвердить/опровергнуть мои выводы. Если у вас есть знания в этой области, я хотел бы поделиться некоторыми своими выводами (конечно, на частном канале). Для меня это будет большой честью! - person Roi Mulia; 31.08.2017
comment
@RoiMulia извините, но я никогда не использовал AVMutableComposition API, так что это не сильно поможет… - person Rob Keniger; 31.08.2017
comment
@RobKeniger Ха-ха, все в порядке. Спасибо, Роб. Хороших выходных! - person Roi Mulia; 31.08.2017

Важно отметить, что система координат вида — верхний левый угол, тогда как CIImage — нижний левый. Это сведет вас с ума, если вы не поймаете это, когда будете делать эти преобразования! В этом другом посте описывается однонаправленное преобразование: Изменение значения CGrect на пользовательскую систему координат< /а>.

person Chris Vander Mey    schedule 23.06.2012
comment
Это заставляло меня сомневаться в своем здравомыслии... Спасибо! - person Munib; 29.12.2016

Вот как работает CICrop — он обрезает указанный вами прямоугольник, а необрезанная область становится прозрачной. Если вы напечатаете extent, вы увидите, что это все тот же исходный прямоугольник.

Как было предложено, вы можете сделать перевод. Теперь это всего 1 строка в Swift 5:

let newImage = myCIImage.transformed(by: CGAffineTransform(translationX: -150, y: -150)
person samwize    schedule 24.08.2019