LoginSignup
2
4

More than 5 years have passed since last update.

Swift:CALayerや画像に射影変換を適用する

Posted at

はじめに

CAlayerや画像に射影変換を適用する時のTipsを残す.
併せてこちらの記事も参照するといいかもしれない.

CALayer編

let layer = CALayer()
self.view.wantsLayer = true //macOSだと必要
self.view.layer?.addSublayer(layer) //親のビューは状況による
layer.frame = self.view.bounds

//layerに何かしらコンテンツを入れる

let rect = CGRect(x: 0, y: 0, width: W, height: H) // コンテンツの大きさ
let filter = CIFilter(name: "CIPerspectiveTransformWithExtent")!
filter.setValue(CIVector(cgRect: rect, forKey: "inputExtent")
filter.setValue(CIVector(x: X1, y: Y1), forKey: "inputTopLeft") //射影変換後のコンテンツ左上頂点の座標
filter.setValue(CIVector(x: X2, y: Y2), forKey: "inputTopRight") //射影変換後のコンテンツ右上頂点の座標
filter.setValue(CIVector(x: X3, y: Y3), forKey: "inputBottomRight") //射影変換後のコンテンツ右下頂点の座標
filter.setValue(CIVector(x: X4, y: Y4), forKey: "inputBottomLeft") //射影変換後のコンテンツ左下頂点の座標

layer.filters = [filter]

画像編

var nsImage = NSImage(name: "hoge")!
let imageData = nsImage.tiffRepresentation!
var ciImage = CIImage(data: imageData)!

let filter = CIFilter(name: "CIPerspectiveTransformWithExtent")!
filter.setValue(ciImage, forKey: "inputImage")
filter.setValue(CIVector(cgRect: ciImage.extent), forKey: "inputExtent")
filter.setValue(CIVector(x: X1, y: Y1), forKey: "inputTopLeft") //射影変換後のコンテンツ左上頂点の座標
filter.setValue(CIVector(x: X2, y: Y2), forKey: "inputTopRight") //射影変換後のコンテンツ右上頂点の座標
filter.setValue(CIVector(x: X3, y: Y3), forKey: "inputBottomRight") //射影変換後のコンテンツ右下頂点の座標
filter.setValue(CIVector(x: X4, y: Y4), forKey: "inputBottomLeft") //射影変換後のコンテンツ左下頂点の座標

ciImage = filter.outputImage!
let rep = NSCIImageRep(ciImage: ciImage)
nsImage = NSImage(size: rep.size)
nsImage.addRepresentation(rep)

補足

CIPerspectiveTransformWithExtentが射影変換用のフィルタなのかは不明ですが,射影変換を手軽に達成できるのでいいですね.しかし,このCIPerspectiveTransformWithExtentは各頂点のパラメータ次第で結果がちゃんと出力されないので要注意です.色々試した感じだと,元のコンテンツより大き過ぎたり,どこかの辺が水平or垂直だとダメ(?)っぽい.引き伸ばしの限界があるのか,ゼロで割っちゃうのかよくわかりません.出力できる時はできる.

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4