今回の記事はSwiftでカメラアプリの作り方をご紹介する記事です。アプリ内でカメラを表示するところまでを初心者でも分かりやすいように記載します。是非、カメラアプリを作ってみようと考えている方は参考にして見てください。
Swiftのカメラアプリ環境構築
まずはXcodeアプリを作成するのでXcodeをインストールして使用できるまで行いましょう。
通常のアプリを作成してで環境構築完了です。
カメラをアプリで使用する際の権限設定
「info.plist」を設定し、アプリにカメラ関連の権限を付与していきます。
「Privacy-Photo Library Additions Usage Description」「Privacy-Camera Usage Description」の設定を追加しましょう。
カメラを画面に表示する方法
実装は下記です。
import UIKit
import Foundation
import AVFoundation
class ViewController: UIViewController,AVCaptureVideoDataOutputSampleBufferDelegate,UIGestureRecognizerDelegate, AVCapturePhotoCaptureDelegate {
//カメラ関連 セッション デバイス 出力
var session: AVCaptureSession!
var device: AVCaptureDevice!
var output: AVCaptureVideoDataOutput!
//保存用Image
var saveimg:UIImage? = nil
// カメラ表示用imageview
@IBOutlet weak var CameraImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// カメラの初期設定
if initCamera() {
session.startRunning()
}else{
assert(false) //カメラが使えない
}
// Do any additional setup after loading the view.
}
// カメラの準備処理
func initCamera() -> Bool {
//解像度 フレームレート カメラ向き
let preset = AVCaptureSession.Preset.hd4K3840x2160
let frame = CMTimeMake(value: 1, timescale: 20) //
let position = AVCaptureDevice.Position.back
setImageViewLayout(preset: preset)//UIImageViewの大きさを調整
// セッションの作成.
session = AVCaptureSession()
// 解像度の指定.
session.sessionPreset = preset
// デバイス取得.
device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera,for: AVMediaType.video,position: position)
//AVCaptureDevice.default(AVCaptureDevice.DeviceType.
// VideoInputを取得.
var input: AVCaptureDeviceInput! = nil
do {
input = try
AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput
} catch let error {
print(error)
return false
}
// セッションに追加.
if session.canAddInput(input) {
session.addInput(input)
} else {
return false
}
// 出力先を設定
output = AVCaptureVideoDataOutput()
//ピクセルフォーマットを設定
output.videoSettings =
[ kCVPixelBufferPixelFormatTypeKey as AnyHashable as! String : Int(kCVPixelFormatType_32BGRA) ]
//サブスレッド用のシリアルキューを用意
output.setSampleBufferDelegate(self, queue: DispatchQueue.main)
// 遅れてきたフレームは無視する
output.alwaysDiscardsLateVideoFrames = true
// FPSを設定
do {
try device.lockForConfiguration()
device.activeVideoMinFrameDuration = frame //フレームレート
device.unlockForConfiguration()
} catch {
return false
}
// セッションに追加.
if session.canAddOutput(output) {
session.addOutput(output)
} else {
return false
}
// カメラの向きを合わせる
for connection in output.connections {
if connection.isVideoOrientationSupported {
connection.videoOrientation = AVCaptureVideoOrientation.portrait
}
}
return true
}
// 画像を出力
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
DispatchQueue.main.async{ [self] in //非同期処理として実行
let img = self.captureImage(sampleBuffer) //UIImageへ変換
var resultImg: UIImage //結果を格納する
resultImg = img
// 表示
self.CameraImageView.image = resultImg
saveimg = resultImg
}
}
// 動画のbufferを画像に変換
func captureImage(_ sampleBuffer:CMSampleBuffer) -> UIImage{
let imageBuffer: CVImageBuffer! = CMSampleBufferGetImageBuffer(sampleBuffer)
// ベースアドレスをロック
CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
// 画像データの情報を取得
let baseAddress: UnsafeMutableRawPointer = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0)!
let bytesPerRow: Int = CVPixelBufferGetBytesPerRow(imageBuffer)
let width: Int = CVPixelBufferGetWidth(imageBuffer)
let height: Int = CVPixelBufferGetHeight(imageBuffer)
// RGB色空間を作成
let colorSpace: CGColorSpace! = CGColorSpaceCreateDeviceRGB()
// Bitmap graphic contextを作成
let bitsPerCompornent: Int = 8
let bitmapInfo = CGBitmapInfo(rawValue: (CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) as UInt32)
let newContext: CGContext! = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: bitsPerCompornent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) as CGContext?
// Quartz imageを作成
let imageRef: CGImage! = newContext!.makeImage()
// ベースアドレスをアンロック
CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
// UIImageを作成
let resultImage: UIImage = UIImage(cgImage: imageRef)
saveimg = resultImage
return resultImage
}
// カメラの表示サイズ
func setImageViewLayout(preset: AVCaptureSession.Preset){
let width = self.view.frame.width
var height:CGFloat
switch preset {
case .photo:
height = width * 852 / 640
case .high:
height = width * 1280 / 720
case .medium:
height = width * 480 / 360
case .low:
height = width * 192 / 144
case .cif352x288:
height = width * 352 / 288
case .hd1280x720:
height = width * 1280 / 720
default:
height = self.view.frame.height
}
CameraImageView.frame = CGRect(x: 0, y: 0, width: width, height: height)
}
}
上記コードの解説を行なっていきます。まずはdelegateに下記を追加します。
,AVCaptureVideoDataOutputSampleBufferDelegate,UIGestureRecognizerDelegate, AVCapturePhotoCaptureDelegate
セッション等必要な情報を定義します。
//カメラ関連 セッション デバイス 出力
var session: AVCaptureSession!
var device: AVCaptureDevice!
var output: AVCaptureVideoDataOutput!
//保存用Image
var saveimg:UIImage? = nil
カメラを設定するためには「initCamera()」「captureOutput()」「captureOutput()」「setImageViewLayout()」の4つの関数だけで実装できます。
カメラアプリの機能追加
カメラアプリで例えば画像を撮影し、カメラロールに画像を保存したり画面サイズを変更したりなどの機能もあります。詳しい内容は下記リンクより記載しているので興味ある方は是非見て見てください。
- カメラアプリで画像を撮影する方法
- カメラアプリのカメラサイズを変更
- 背面カメラと前面カメラを設定する方法
随時追加していきます。
今回の記事は以上です。他にもSwift関連の記事を記載しているので興味ある方は是非サイト内見ていってください。
コメント