はじめに
こんにちはこんばんはおはようございます!25Bのあーる(@ruraruto246)と申します。
実は、高校生の頃からSwiftを使ってスマホアプリを作り続けている生粋のmacユーザです!最近は容量の限界でwindowsをよく使ってますが、、、
今回は個人開発した自作ピン写ポーズ提案アプリを元に、Swiftのみでのオリジナルカメラの作り方を紹介します!
自作アプリ紹介(ただの宣伝)
IBum - 誰でもおしゃれなピン写が集まるカメラ&アルバムアプリ
急にアイコンを自分の顔が映った写真にしないといけなくなった時!このアプリがあれば誰でもおしゃれなピン写(自分だけが映った写真)を撮れます!ぜひダウンロードしてみてください!

開発環境
macOS 15.6
Xcode 16.4
iOS 18.5
この記事を読んで欲しい人
- 純正のカメラにオリジナル機能を付けたい人
- カメラの実装方法の使い分けを知りたい人
ここから実際の実装について書いていきます!
カメラを実装するために何が使えるのか
iOS18.5時点ではUIImagePickerController
とAVCaputureSession
のどちらかを使用します。以下に違いをまとめます。
クラス名 | UIImagePickerController | AVCaputureSession |
---|---|---|
フレームワーク | UIKit | AVFoundation |
実装難易度 | 簡単 | 難しい |
カスタマイズ | 難しい | 簡単 |
プレビュー | View | Layer |
特に何もカスタマイズしない場合、それぞれ以下のような画面が実装されます。
UIImagePickerController
AVCaputureSession
AVCapturesession自体には実はズームどころか写真を撮るボタンもありません!
結局どちらを使えばいい?
-
純正のカメラに近い挙動を実装したい
-
とりあえず写真or動画を撮影できる機能をつけたい
-
写真の比率には拘らない
→UIImagePickerController
-
撮影した画像に特殊な編集を加えたい
-
撮影画面UIを独自のものにしたい
-
撮影時の比率を指定したい
→AVCaputureSession
私なりの見解ですが参考にしていただければ幸いです!
今回作ったオリジナルカメラの紹介
今回は動画のように
- 選択された撮影したシルエットの表示、非表示設定
- 構図のバランスをとりやすい点線表示
- 3:2の比率に固定して表示
- ズームインアウト
- 撮影後の3:2の比率のまま編集
を取り入れたカメラアプリを作成しました!
この記事では特にこだわった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さんです!お楽しみに!