質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

434閲覧

[Swift4 Xcode9]アップデートによるカメラの不具合(表示されない)

ghana

総合スコア18

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/10/18 06:35

###前提・実現したいこと
・背景
最近、間違えてiPhoneのiOSをバージョンアップしてしまい同時にXcodeもバージジョンアップしないといけなくなり、バージョンアップをしてSwift4,Xcode9にしたところ今まで、呼び出せていたカメラが呼び出せなくなりました。(具体的には、カメラが取得した画像がリアルタイムに表示されず真っ白な状態になっている)

・試したこと
前回のSwift3のアップデートはinfo.plistが原因でしたが、今回は
Privacy - Camera Usage Description と
Privacy - Photo Library Additions Usage Descriptionが追加してあるのでinfo.plistが原因ではないということがわかっているのですが、どこのコードが不具合を起こしているなど見つけられず手詰まりとなっています。

お手数をおかけしますがご教授お願いいたします。

###該当のソースコード
CameraUtil.swift

import Foundation import UIKit import AVFoundation import SpriteKit class CameraUtil { //sampleBufferからUIImageへ変換 class func imageFromSamleBuffer(_ sampleBuffer: CMSampleBuffer) -> UIImage { let imageBuffer: CVImageBuffer! = CMSampleBufferGetImageBuffer(sampleBuffer) //ベースアドレスをロック CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: CVOptionFlags(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: CVOptionFlags(0))) //UIImage作成 let resultImage: UIImage = UIImage(cgImage: imageRef) return resultImage } }

ViewController.swift

import UIKit import AVFoundation import SpriteKit class ViewController: UIViewController { @IBOutlet weak var viewImage: UIImageView! //セッション キャプチャに関する入力と出力の管理 var mySession : AVCaptureSession! //カメラデバイス カメラやマイクといったデバイスそのものを表現 var myDevice : AVCaptureDevice! //出力先 サブクラス 動画フレームデータ var myOutput : AVCaptureVideoDataOutput! //カメラの準備処理 func initCamera() -> Bool { //セッションの作成 mySession = AVCaptureSession() //解像度の指定 mySession.sessionPreset = AVCaptureSession.Preset.vga640x480 //デバイス一覧の取得 let devices = AVCaptureDevice.devices() //バックカメラをmyDeviceに格納 for device in devices { //全面か背面かの指定(どちらかをコメントアウトしておくこと) //全面 //if((device as AnyObject).position == AVCaptureDevicePosition.front){ //背面 if((device as AnyObject).position == AVCaptureDevice.Position.back){ myDevice = device } } if myDevice == nil{ return false } //バックカメラからVideoInputを取得 var myInput : AVCaptureDeviceInput! = nil do { myInput = try AVCaptureDeviceInput(device: myDevice) as AVCaptureDeviceInput } catch let error { print(error) } //セッションに追加 if mySession.canAddInput(myInput){ mySession.addInput(myInput) } else { return false } //出力先を設定 myOutput = AVCaptureVideoDataOutput() myOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable as! String:Int(kCVPixelFormatType_32BGRA)] //FPSを設定 do { try myDevice.lockForConfiguration() myDevice.activeVideoMinFrameDuration = CMTimeMake(1, 30) myDevice.unlockForConfiguration() } catch let error { print("lock error: (error)") return false } //デリケートを設定 let queue: DispatchQueue = DispatchQueue(label: "myqueue", attributes: []) myOutput.setSampleBufferDelegate(self as? AVCaptureVideoDataOutputSampleBufferDelegate, queue: queue) //遅れてきたフレームは無視するかしないか myOutput.alwaysDiscardsLateVideoFrames = true //セッションに追加 if mySession.canAddOutput(myOutput){ mySession.addOutput(myOutput) } else { return false } //カメラの向きを合わせる for connection in myOutput.connections{ let conn = connection if conn.isVideoOrientationSupported{ conn.videoOrientation = AVCaptureVideoOrientation.portrait } } return true } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. //カメラを準備 if initCamera(){ mySession.startRunning() } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //毎フレーム実行される処理 func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!){ //同期処理(非同期処理ではキューが溜まりすぎて画面がついていけない) DispatchQueue.main.sync(execute:{ //CMSampleBufferRefからUIImageへ変換 let image = CameraUtil.imageFromSamleBuffer(sampleBuffer) self.viewImage.image = image }) } }

###補足情報(言語/FW/ツール等のバージョンなど)
Xcode9 Swift4 iOS11

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。
どうやらViewController.swiftのfunc captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!)のdidOutputSampleBufferがアップデートによってdidOutputに変更しないといけなかったようです。

投稿2017/10/20 01:15

ghana

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問