【Swift】2枚の画像の間違い探し。画素同士の色情報の比較など。
サイゼリヤの間違い探しが難しすぎたので大人の力で解決したという素晴らしい記事に感激して、swiftでも似たようなことができないかなと考えていたところ、とりあえず画像同士の比較として画素の色情報を一個一個比較すれば間違い探しができるなあと思ってそういうコードを書いてみました。
各画素情報を取得するやり方は、QiitaとSwiftサラリーマンさんの以下のリンク先の記事を参考にしました。ありがとうございます。
[Swift] 画像の特定のピクセルの色を調べる
Swiftサラリーマン UIImageの色情報を抜き出す
(Swiftサラリーマンさんのサイトはかなり勉強になります。)
とりあえず以下の2枚の画像を用意。
コードとしては、各画像の一個一個のピクセルの色情報を抜き出しては比較し、imageTmpという1ピクセルのUIImageViewを作って、一緒ならその色情報をimageTmpの背景色として設定、異なっていたら黒を背景色として設定して画面に表示する、というのを、画像サイズ分だけ繰り返しています。
誤算だったのは、ピクセルを抜き出す処理というのが想定外に時間がかかるということ。
上記各々の画像は162✖︎147ピクセルですが、私のmacbook airのシミュレータで計算結果が出るまでに10秒くらいかかります。
実際はhttp://www.saizeriya.co.jp/entertainment/サイゼリヤの間違い探しのサイトから、各画像が取得できるので、ダウンロードしてから左と右の画像を分割、そして各々の画素同士を比較というプログラムを書いてみたのですが、画像サイズがでかすぎて処理が全然終わらず、かといってサイズ縮小してみたら、小さすぎて目視で判断するのが困難なくらいになってしまいました。
処理スピードどうやったらあげられるかなということと、将来的にはその場で写真を撮ってそれを用いて間違い探ししてみるというコードを書いてみたいですが、修行が足りなすぎてまだまだです。
以下、コード。
import UIKit class ViewController: UIViewController { let button: UIButton = UIButton() let image :UIImageView = UIImageView() let image2 :UIImageView = UIImageView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. image.image = UIImage(named: "icon-1024.png") image.frame = CGRectMake(0, 0, self.image.image!.size.width, self.image.image!.size.height) image2.image = UIImage(named: "icon-1024-2.png") image2.frame = CGRectMake(self.image.image!.size.width, 0, self.image.image!.size.width, self.image.image!.size.height) self.view.addSubview(image) self.view.addSubview(image2) button.frame = CGRectMake(UIScreen.mainScreen().bounds.width/2, UIScreen.mainScreen().bounds.height*4/5,50,50) button.setTitle("push", forState: .Normal) button.backgroundColor = UIColor.yellowColor() button.setTitleColor(UIColor.blackColor(), forState: .Normal) button.addTarget(self, action: "spotDifference", forControlEvents: .TouchUpInside) self.view.addSubview(button) } func spotDifference () { for var i=0; i < Int(self.image.image!.size.width); i++ { for var j=0; j < Int(self.image.image!.size.height); j++ { print(i) print(j) let imageTmp: UIImageView = UIImageView() imageTmp.frame = CGRectMake(CGFloat(self.image.image!.size.width*2)+CGFloat(i), CGFloat(j), 1, 1) if getPixelColorFromUIImage(image.image!,pos: CGPoint(x:CGFloat(i), y:CGFloat(j))) == getPixelColorFromUIImage(image2.image!,pos: CGPoint(x:CGFloat(i), y:CGFloat(j))) { imageTmp.backgroundColor = getPixelColorFromUIImage(image.image!,pos: CGPoint(x:CGFloat(i), y:CGFloat(j))) }else { imageTmp.backgroundColor = UIColor.blackColor() } self.view.addSubview(imageTmp) } } } func getPixelColorFromUIImage(image3:UIImage, pos: CGPoint) -> UIColor { let pixel = CGDataProviderCopyData(CGImageGetDataProvider(image3.CGImage)) let data: UnsafePointer = CFDataGetBytePtr(pixel) let pixelColor: Int = ((Int(image3.size.width) * Int(pos.y)) + Int(pos.x)) * 4 let r = CGFloat(data[pixelColor]) / CGFloat(255.0) let g = CGFloat(data[pixelColor+1]) / CGFloat(255.0) let b = CGFloat(data[pixelColor+2]) / CGFloat(255.0) let a = CGFloat(data[pixelColor+3]) / CGFloat(255.0) return UIColor(red: r, green: g, blue: b, alpha: a) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }