0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOSAdvent Calendar 2021

Day 15

画像をマスク合成するときに、短いコードで縦横比率を計算してはみ出さないようにする

Last updated at Posted at 2021-12-15

合成画像がはみ出さないようにする簡単な方法を書きます。
スクリーンショット 2021-12-15 10 07 46
【縦横に思い切りはみ出すfrontImage】

縦横比のちがう2枚の画像をマスク合成するときに、
場合によっては画像がはみ出してしまう。

###はみ出してしまう原因

はみ出さないように画像をスケール変更しないといけないのだが、
合成するFrontImageとBackgroundImageがあるとき、

FrontImageの横と縦どちらが長いか。
BackgroundImageの横と縦どちらが長いか。
FrontImageの縦とBackgroundImageの縦どちらが長いか。
FrontImageの横とBackgroundImageの横どちらが長いか。

の組み合わせがあり、はみ出しがないように全てのパターンを記述するのは面倒くさい。
僕は最初「短い方の辺で合わせればいいんだな」と思ってスケールを設定すると、横だけはみ出したりした。

単純に2枚の画像を合成する場合は、
CIMinimumCompositing
を使えばはみ出さないように計算してくれるが、
マスク画像の場合は計算してくれるフィルターはなく、単純に画像の座標とサイズで合成される。

###解決法

そこで、全てのパターンをカバーし、FrontImageがBackgroundImageからはみ出さない、
かつ、なるべく大きく表示されるように合成するには以下のスケール計算をすれば良い。

var scale:CGFloat = 1

// あらかじめ画像同士の縦横それぞれの比を計算し、スケールが小さい方に合わせる
let widthScale = backgroundCIImage.extent.width / frontCIImage.extent.width
let heightScale = backgroundCIImage.extent.height / frontCIImage.extent.height
        
if widthScale < heightScale {
    scale = backgroundCIImage.extent.width / frontCIImage.extent.extent.width
} else {
    scale = backgroundCIImage.extent.height / frontCIImage.extent.extent.height
}

let transform = CGAffineTransform(scaleX: scale, y: scale)

let scaledFrontCIImage = frontCIImage.transformed(by: transform)
// マスク画像をfrontImageに合わせる場合、同様にスケールする。
スクリーンショット 2021-12-15 10 07 30 【ちゃんと収まったFrontImage】 🐣 **** フリーランスエンジニアです。 お仕事のご相談こちらまで 簡単な開発内容をお書き添えの上、お気軽にご連絡ください。 rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習/AR関連の情報を発信しています。

Twitter
Medium

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?