Подтвердить что ты не робот

Cropping CIImage с CICrop работает неправильно

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

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

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: (я нарисовал границу для ясности)

enter image description here

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

enter image description here

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

enter image description here

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

4b9b3361

Ответ 1

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

Фильтр 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"];

Ответ 2

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

Ответ 3

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

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

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