質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2418閲覧

swift 画像のマスクと背景合成

aaru

総合スコア1

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/04/25 22:44

編集2021/04/26 01:20

前提・実現したいこと

Swiftで画像のマスク、背景合成を行いたいのですが、方法がわからず困っております。
ネットで調べサンプルなどを見ながら、マスク画像と元画像より切り抜いた画像の作成は行えたのですが、背景(別画像)との
合成の方法がわかりません。
また、切り抜いた画像をUIImageViewに表示、その後カメラロールに保存して見ると、切り抜く前のオリジナルの画像となってしまいます。

該当のソースコード

swift

1 @IBAction func combinedTap(_ sender: Any) { 2 let si = UIImage.init(named: "org.jpg") 3 let mi = UIImage.init(named: "mask.jpg") 4 self.displayView.image = si?.masking(maskImage: mi) 5 6// 7// 本来はここで背景を読みこんんで合成を行いたいです 8// 9 10// 確認用にカメラロールへ保存 11 //タップしたUIImageViewを取得 12 let targetImageView = self.displayView 13 // その中の UIImage を取得 14 let targetImage = targetImageView!.image! 15 //保存するか否かのアラート 16 let alertController = UIAlertController(title: "保存", message: "この画像を保存しますか?", preferredStyle: .alert) 17 //OK 18 let okAction = UIAlertAction(title: "OK", style: .default) { (ok) in 19 //ここでフォトライブラリに画像を保存 20 UIImageWriteToSavedPhotosAlbum(targetImage, self, #selector(self.showResultOfSaveImage(_:didFinishSavingWithError:contextInfo:)), nil) 21 } 22 //CANCEL 23 let cancelAction = UIAlertAction(title: "CANCEL", style: .default) { (cancel) in 24 alertController.dismiss(animated: true, completion: nil) 25 } 26 //OKとCANCELを表示追加し、アラートを表示 27 alertController.addAction(cancelAction) 28 alertController.addAction(okAction) 29 present(alertController, animated: true, completion: nil) 30 31 } 32 33extension UIImage { 34 func masking(maskImage: UIImage?) -> UIImage? { 35 guard let maskImage = maskImage?.cgImage else { 36 return nil 37 } 38 let mask = CGImage(maskWidth: maskImage.width, 39 height: maskImage.height, 40 bitsPerComponent: maskImage.bitsPerComponent, 41 bitsPerPixel: maskImage.bitsPerPixel, 42 bytesPerRow: maskImage.bytesPerRow, 43 provider: maskImage.dataProvider!, 44 decode: nil, shouldInterpolate: false)! 45 46 guard let maskedImage = self.cgImage?.masking(mask) else { 47 return nil 48 } 49 return UIImage(cgImage: maskedImage) 50 }

画像です
マスク画像
イメージ説明
オリジナル画像
イメージ説明

self.displayView.image = si?.masking(maskImage: mi)
の後にself.displayView.imageをカメラロールに保存しているのですが、オリジナルの画像が保存され、切り抜き画像の保存が行えません。画面での見た目は、切り抜かれた画像(犬)が表示されています。
切り抜き画像の保存方法と切り抜き画像と別に用意した背景画像の合成方法をお教えいただけませんでしょうか。

追記
CIFilterを使用し、合成を行うことができました。

Swift

1 let si = UIImage.init(named: "org.jpg") 2 let mi = UIImage.init(named: "mask.jpg") 3 let bi = UIImage.init(named: "photo.jpg") 4 5 let sci = CIImage(image: si!) 6 let mci = CIImage(image: mi!) 7 let bci = CIImage(image: bi!) 8 9 let compositeImage = CIFilter(name: "CIBlendWithMask", parameters: [ 10 kCIInputImageKey: sci, 11 kCIInputBackgroundImageKey:bci, 12 kCIInputMaskImageKey:mci])?.outputImage 13 self.displayView.image = UIImage(ciImage: compositeImage!)

ただ、合成後の画像がカメラロールに保存できないです。
保存完了のメッセージは出るのですが、カメラロールに存在しません。
何か確認すべき点などございませんでしょうか。

追記2
CIIImageからUIImageへの変換を一旦、CGImageに変換しUIImageに変換することで保存出来ました

swift

1 let context = CIContext() 2 let cgImage = context.createCGImage(compositeImage!,from: compositeImage!.extent) 3 let image2 = UIImage(cgImage: cgImage!) 4 self.displayView.image = image2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tomato879241

2021/04/25 23:16

Core Imageのフィルターでできるか確認しましたか?
aaru

2021/04/26 01:00

tomato879241さま ありがとうございます! CIFilterでうまく合成することができました。 ただ、合成後の画像の保存ができませんでした。 ソースについては別途、質問欄に追記いたします。
tomato879241

2021/04/26 01:09

CIFilterを使うときの最終画像は「outputImage」。それはCIIImageなので、それをUIImageに変換してください。
aaru

2021/04/26 01:17

self.displayView.image = UIImage(ciImage: compositeImage!) で変換を行っているつもりなのですが、これでは変換出来ないのですね 一旦、CGImageに変換しUIImageにすることにより保存出来ました。
guest

回答1

0

自己解決

Swift

1//合成 2 let si = UIImage.init(named: "org.jpg") 3 let mi = UIImage.init(named: "mask.jpg") 4 let bi = UIImage.init(named: "photo.jpg") 5 6 let sci = CIImage(image: si!) 7 let mci = CIImage(image: mi!) 8 let bci = CIImage(image: bi!) 9 10 let compositeImage = CIFilter(name: "CIBlendWithMask", parameters: [ 11 kCIInputImageKey: sci, 12 kCIInputBackgroundImageKey:bci, 13 kCIInputMaskImageKey:mci])?.outputImage 14 self.displayView.image = UIImage(ciImage: compositeImage!) 15 16//保存の為にUIImageへ変換 17 let context = CIContext() 18 let cgImage = context.createCGImage(compositeImage!,from: compositeImage!.extent) 19 let image2 = UIImage(cgImage: cgImage!) 20 self.displayView.image = image2 21

投稿2021/04/26 01:21

編集2021/04/26 01:35
aaru

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問