feature image

2025年9月1日 | ブログ記事

Swiftでオリジナルカメラを作った話【夏のブログリレー2025 15日目】

はじめに

こんにちはこんばんはおはようございます!25Bのあーる(@ruraruto246)と申します。
実は、高校生の頃からSwiftを使ってスマホアプリを作り続けている生粋のmacユーザです!最近は容量の限界でwindowsをよく使ってますが、、、

今回は個人開発した自作ピン写ポーズ提案アプリを元に、Swiftのみでのオリジナルカメラの作り方を紹介します!

自作アプリ紹介(ただの宣伝)

IBum - 誰でもおしゃれなピン写が集まるカメラ&アルバムアプリ

急にアイコンを自分の顔が映った写真にしないといけなくなった時!このアプリがあれば誰でもおしゃれなピン写(自分だけが映った写真)を撮れます!ぜひダウンロードしてみてください!

‎Ibum
‎誰でもおしゃれなピン写が集まる新感覚カメラ&アルバムアプリ - IBum ピン写を撮りたいけどどんなポーズが良いのかわからない、アイコンに使えそうなピン写が見当たらない、ピン写を撮るのも撮ってもらうのも恥ずかしい、そんな悩みを抱えた人をIBumが助けます。 機能1.ポーズ提案15種類のポーズから、自分の状況にピッタリなものを選ぶことができます。タグ、クエスト、シルエット画像、お気に入りなど様々な角度から一番自分にピッタリなものが見つかります。機能2.撮影お願い機能好きなポーズを選んだら、仲間に撮影をお願いしましょう!スマホを画面を見せるだけで撮ってほしいポーズを一瞬で伝えることができ…

開発環境

macOS 15.6
Xcode 16.4
iOS 18.5

この記事を読んで欲しい人

ここから実際の実装について書いていきます!

カメラを実装するために何が使えるのか

iOS18.5時点ではUIImagePickerControllerAVCaputureSessionのどちらかを使用します。以下に違いをまとめます。

クラス名 UIImagePickerController AVCaputureSession
フレームワーク UIKit AVFoundation
実装難易度 簡単 難しい
カスタマイズ 難しい 簡単
プレビュー View Layer

特に何もカスタマイズしない場合、それぞれ以下のような画面が実装されます。

UIImagePickerController

0:00
/

AVCaputureSession

0:00
/

AVCapturesession自体には実はズームどころか写真を撮るボタンもありません!

結局どちらを使えばいい?

私なりの見解ですが参考にしていただければ幸いです!

今回作ったオリジナルカメラの紹介

今回は動画のように

  1. 選択された撮影したシルエットの表示、非表示設定
  2. 構図のバランスをとりやすい点線表示
  3. 3:2の比率に固定して表示
  4. ズームインアウト
  5. 撮影後の3:2の比率のまま編集

を取り入れたカメラアプリを作成しました!

0:00
/

この記事では特にこだわった3:2の比率に固定して表示の部分のコードを紹介します!

プレビュー表示時

//カメラ用のviewを生成
let cameraUIview = UIView()
//カメラ用のViewのサイズを3:2に指定
cameraUIview.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: self.view.frame.width, height: self.view.frame.width / 2 * 3))
self.view.addSubview(cameraUIview)
//AutoLayoutを設定して画面を上部に固定する
cameraUIview.translatesAutoresizingMaskIntoConstraints = false
cameraUIview.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true             
//camerauiviewにcameralayerを追加
self.cameraPreviewLayer?.frame = cameraUIview.frame
cameraUIview.layer.insertSublayer(self.cameraPreviewLayer!, at: 0)

AutoLayoutを入れないと若干ずれてしまい既存のカメラのようなレイアウトが作れなくなるので必ず設定しましょう!

撮影時

// 撮影した画像データが生成されたときに呼び出されるデリゲートメソッド
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if let imageData = photo.fileDataRepresentation() {
       // Data型をUIImageオブジェクトに変換
       let uiImage = UIImage(data: imageData)!
       //撮影した画像を画面サイズに会うように切り取り
       let cgImage = uiImage.cgImage?.cropping(to:CGRect(x: 0, y: 0, width: uiImage.size.height, height:uiImage.size.height / 3 * 2))
       //編集画面へ渡すために切り抜いた画像を再度UIImageに変換
       let image = UIImage(cgImage: cgImage! ,scale: 0, orientation: uiImage.imageOrientation)
        }
    }

croppingを行わないと4:3の比率の画像となってしまう(カメラで見ていた部分より広い部分が映る)ので注意してください。

他の機能に関しては他の素晴らしい記事を参考にしてください。

おわりに

今回UIのフレームワークとしてはSwiftUIを採用しています。が、SwiftUIのみで実装できる純正カメラクラスは2025年9月1日現在存在していません!

各所でSwiftUIが採用されることも多くなってきましたが、まだまだUIKitも現役だと思い知らされた開発でした。

明日の投稿者は@ikura-hamuさんです!お楽しみに!

ruraruto246 icon
この記事を書いた人
ruraruto246

25B。スマホアプリの開発をよくする。イラストもよく描く。いろんな技術に触れているTime。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2024年9月17日
1か月でゲームを作った #BlueLINE
Komichi icon Komichi
2024年8月21日
【最新版 / 入門】JUCEを使ってVSTプラグインを作ろう!!!!【WebView UI】
kashiwade icon kashiwade
2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2022年9月16日
5日でゲームを作った #tararira
Komichi icon Komichi
2024年8月29日
クロスコンパイルRust
H1rono_K icon H1rono_K
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記