Базовый фильтр CIPerspectiveTransform изображения:Как использовать CIVectors?
-
12-12-2019 - |
Вопрос
Мне очень трудно найти в Интернете какую-либо документацию, которая четко объясняет, как правильно реализовать фильтр CIPerspectiveTransform Core Image.В частности, при установке значений CIVector для inputTopLeft
, inputTopRight
, inputBottomRight
, и inputBottomLeft
, что эти векторы делают с изображением?(То есть, какова математика того, как эти векторы искажают мое изображение?)
В настоящее время это код, который я использую.Он не вылетает, но не показывает изображение:
CIImage *myCIImage = [[CIImage alloc] initWithImage:self.image];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:@"CIPerspectiveTransform" keysAndValues:@"inputImage", myCIImage, @"inputTopLeft", [CIVector vectorWithX:118 Y:484], @"inputTopRight", [CIVector vectorWithX:646 Y:507], @"inputBottomRight", [CIVector vectorWithX:548 Y:140], @"inputBottomLeft", [CIVector vectorWithX:155 Y:153], nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *transformedImage = [UIImage imageWithCGImage:cgimg];
[self setImage:transformedImage];
CGImageRelease(cgimg);
Другие важные моменты, на которые следует обратить внимание:
Мой UIImageView (75 пикселей x 115 пикселей) уже инициализирован через пробуждениеFromNib и уже имеет связанное с ним изображение (151 x 235 пикселей).
Приведенный выше код реализуется в UIImageView.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
функция.Я надеюсь, что смогу настроить перспективу изображения на основе координат экрана, чтобы оно выглядело так, будто изображение движется в трехмерном пространстве.Этот код предназначен для приложения для iPhone.
Опять же, мне кажется, что я задаю вопрос: что делают различные векторы параметров, но, возможно, я задаю неправильный вопрос.
Следующий пост очень похож, но в нем задается вопрос, почему его изображение исчезает, а не как использовать CIVectors для CIPerspectiveTransform.Он также получил очень мало поддержки, возможно, потому, что он слишком общий:Как я могу использовать фильтр CIPerspectiveTransform
Решение
Как я прокомментировал связанный вопрос, CIPerspectiveTransform недоступно в реализации Core Image для iOS, начиная с iOS 5.1..Вот почему вы и другой спрашивающий в результате не увидели никакого изображения, потому что, скорее всего, ваш CIFilter был нулевым.
Если вы просто хотите реализовать форму перспективы для изображения, есть два разных быстрых способа сделать это в iOS, как я описываю в разделе этот ответ.Один из них — просто использовать правильный вид CATransform3D на уровне UIImageView, но это полезно только для отображения, а не для настройки изображения.
Второй способ — манипулировать изображением с помощью соответствующей матрицы трехмерного преобразования в OpenGL ES.Как я указываю в приведенном выше ответе, у меня есть фреймворк с открытым исходным кодом это оборачивает все это, а в образце FilterShowcase есть пример применения перспективы к входящему видео.Вы можете легко заменить видеовход своим изображением и получить из него изображение после применения эффекта перспективы.
Другие советы
Ооооочень старый пост, но я уверен, что кто-то все равно будет искать такой фильтр:
Следующая функция применяет фильтр к изображению и возвращает то же изображение с перспективой, пытаясь создать эффект отражения с перспективой.(Следующее изображение является всего лишь примером, а не результатом реального тестирования)
Это пример, поэтому вам нужны некоторые корректировки.Цель – создать образ, который как бы является отражением «главного».
Поэтому я добавил к своему представлению два вида изображений, как на изображении.Добавлены ограничения и т. д.
Затем в функции вы увидите, что координаты жестко запрограммированы, поэтому возвращаемое изображение будет идеально соответствовать своему контейнеру — нижнему элементу UIImageView.
func applyperspectiveTransform(imagen: UIImage) -> UIImage
{
var context = CIContext()
var outputImage = CIImage()
var newUIImage = UIImage()
let leftTop = CGPoint(x: self.ImgView.frame.origin.x, y: self.ImgReflection.frame.origin.y + self.ImgReflection.frame.size.height)
let leftBottom = CGPoint(x: self.ImgReflection.frame.origin.x, y: self.ImgView.frame.origin.y + self.ImgView.frame.size.height)
let rightTop = CGPoint(x: self.ImgView.frame.origin.x + self.ImgView.frame.size.width, y: self.ImgReflection.frame.origin.y + self.ImgReflection.frame.size.height)
let rightBottom = CGPoint(x: self.ImgReflection.frame.origin.x + self.ImgReflection.frame.size.width, y: self.ImgView.frame.origin.y + self.ImgView.frame.size.height)
let lT = CIVector(x: leftTop.x, y: leftTop.y)
let lB = CIVector(x: leftBottom.x, y: leftBottom.y)
let rT = CIVector(x: rightTop.x, y: rightTop.y)
let rB = CIVector(x: rightBottom.x, y: rightBottom.y)
let aCIImage = CIImage(image: imagen)
context = CIContext(options: nil);
let perspectiveTransform = CIFilter(name: "CIPerspectiveTransform")!
perspectiveTransform.setValue(lB,forKey: "inputTopLeft")
perspectiveTransform.setValue(rB,forKey: "inputTopRight")
perspectiveTransform.setValue(rT,forKey: "inputBottomRight")
perspectiveTransform.setValue(lT,forKey: "inputBottomLeft")
perspectiveTransform.setValue(aCIImage,forKey: kCIInputImageKey)
outputImage = perspectiveTransform.outputImage!
let cgimg = context.createCGImage(outputImage, from: outputImage.extent)
newUIImage = UIImage(cgImage: cgimg!)
return newUIImage
}
Для этого конкретного эффекта (зеркала) вы можете добавить еще несколько эффектов, например градиент, изменить альфу и т. д.
Приятного кодирования!Надеюсь, поможет
Надеюсь, поможет!