【Swift】画像がギザギザに表示されてしまう問題のTips【画像 粗い】【ジャギー 除去】

# ■ 概要
本記事では、

**Swiftでの開発中において、画像が粗く表示されてしまう**

**→ 画像が「ジャギる」場合の簡単な対処法**

について紹介したいと思います。

# ■ 環境

Xcodeバージョン　：　15.3

# ■ 実装

まずは今回のサンプル実装から。

[CIFilter](https://developer.apple.com/documentation/coreimage/cifilter)の[「CINoiseReduction」](https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CINoiseReduction)フィルターを使用した実装です。

名前の通りでノイズを軽減し、画像がジャギるのを改善するフィルターで、
通常使用の範囲であれば、実装が簡単でとても便利なフィルターです。

<font color="gray">（より高度な「ノイズ除去」やカスタマイズ性の高い「ぼかし処理」として[Metal](https://developer.apple.com/jp/metal/)などのシェーディング言語を使った実装もありますが、実装がかなり大変です…。）</font>

```Swift
import UIKit

class ExternalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .black
        
        let w = CGFloat(view.bounds.size.width)
        let h = CGFloat(view.bounds.size.height)
        
        let imageSize = CGSize(width: w * 0.5, height: w * 0.5)

        // inputのCIImageを生成
        let ciImage = CIImage(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "logo", ofType: "png") ?? ""))
        // ジャギー除去のフィルターをかける
        let filteredCiImage = applyNoiseReductionBlurToImage(inputImage: ciImage ?? CIImage())
        // CIImage → UIImageに変換
        let filteredUiImage = convertCIImageToUIImage(ciImage: filteredCiImage ?? CIImage())

        // 画面中央に画像を配置
        let imageView = UIImageView(frame: CGRect(x: (w - imageSize.width) * 0.5,
                                                  y: (h - imageSize.height) * 0.5,
                                                  width: imageSize.width,
                                                  height: imageSize.height))
        imageView.contentMode = .scaleAspectFit
        
        imageView.image = filteredUiImage
        view.addSubview(imageView)
    }

    // ジャギー除去のCIFilterをかける関数
    func applyNoiseReductionBlurToImage(inputImage: CIImage) -> CIImage? {
    
        guard let noiseReductionFilter = CIFilter(name: "CINoiseReduction") else {
            fatalError("Specified filter does not exist")
        }

        noiseReductionFilter.setValue(inputImage, forKey: kCIInputImageKey)
        
        // これらの値（1.0）は必要に応じて調整する
        noiseReductionFilter.setValue(1.0, forKey: "inputNoiseLevel")
        noiseReductionFilter.setValue(1.0, forKey: "inputSharpness")

        guard let outputImage = noiseReductionFilter.outputImage else {
            fatalError("Failed to get output image from filter")
        }
        
        return outputImage
    }

    // CIImage → UIImageに変換する関数
    func convertCIImageToUIImage(ciImage: CIImage) -> UIImage? {
    
        let context = CIContext()
        
        guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
            fatalError("Failed to create CGImage from CIImage")
        }
        
        return UIImage(cgImage: cgImage)
    }
}

```

# ■ 「ジャギる」って？

「ジャギる」というのは「[ジャギー](https://e-words.jp/w/%E3%82%B8%E3%83%A3%E3%82%AE%E3%83%BC.html)」を動詞化した言い方をしているだけ
なのですが、具体的にどんな状態を指すかというと

例えば、こんな感じの画像データがあるとして
<font color="gray">（ロゴとかを画像データとして表示する機会は多いと思います。）</font>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/5448c5e3-a6af-039d-94fc-ff961411736b.png" width="250">

その画像をシンプルにそのまま表示させます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/3d4d0665-0f06-6362-51bf-cbe33a89d6de.png" width="250">

---

モバイル端末など、比較的小さな画面で表示させる分には目立ちづらかったり
しますが、大きな外部モニターなどに出力すると

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/71230522-6a4a-6d8f-86b0-6e83d3d42f02.jpeg" width="500">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/e30cc545-0aa6-2036-9e04-bf4929cd899d.jpeg" width="250">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/9716b030-e107-cea7-f310-cfbc8d663855.jpeg" width="250">

こんな感じに輪郭部分がギザギザになってしまうことがあります。
<font color="gray">（外部モニターに出力したものを、普通に写真で撮ったので
分かりづらいと思いますが、画像を拡大表示してもらうと
文字の輪郭がジャギっていることが確認できると思います。）</font>

# ■ 解決法

このジャギーの原因はいくつか考えられ、

**・画像を高解像度で書き出す**
**・画像サイズを「2の乗数」で書き出す**
**・モニター表示設定を適切なものに変更する**

これらの対処法でジャギーが改善されるケースもあります。

しかし、どうしても原因や対処法の見当がつかない場合は
[「アンチエイリアス」](https://www.mb.ccnw.ne.jp/kontoshi/papa/gimon/anti.htm)によって、画像に「ぼかし」をかけて
ジャギー除去をするのが効果的です。

---

CIFilterの「CINoiseReduction」フィルターで
アンチエイリアスをかけた結果…

↓

**【Before（ 画像 : 左 ）】　【After （ 画像 : 右 ）】**

<font color="gray">（色味が若干異なるのは写真撮影時のライトの影響で、
フィルターによるものではありません。こちらも画像を拡大して
比較してもらうと違いが分かりやすいと思います。）</font>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/71230522-6a4a-6d8f-86b0-6e83d3d42f02.jpeg" width="250">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/09595926-bc6d-a89a-7f38-02ed13523ec9.jpeg" width="250">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/e30cc545-0aa6-2036-9e04-bf4929cd899d.jpeg" width="250">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/8ebf6d0c-a3e0-3fb9-41b1-73a4351c1bbc.jpeg" width="250">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/9716b030-e107-cea7-f310-cfbc8d663855.jpeg" width="250">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/ce354daf-822e-7799-be10-d1dea0498d5c.jpeg" width="250">





# ■ 最後に （感想）

今回はCIFilterによる簡単な画像処理について紹介しました。
特に初学者の方とかは、画像を綺麗に表示させるために「ぼかし」をかける、
という発想自体なかなか思い浮かばなかったりするかと思うので
今回の記事が手助けになれば幸いです。

最後まで読んでいただきありがとうございました。