質問するログイン新規登録

質問編集履歴

5

動作確認済みソースコード編集

2018/08/03 10:58

投稿

nobu09
nobu09

スコア35

title CHANGED
File without changes
body CHANGED
@@ -12,19 +12,100 @@
12
12
  ### 該当のソースコード[編集]
13
13
 
14
14
  ```swift
15
- func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
16
- let image = self.imageFromSampleBuffer(sampleBuffer: sampleBuffer)
15
+ class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
16
+
17
+ @IBOutlet var previewView: UIImageView!
18
+
19
+ var session = AVCaptureSession()
17
- // addImage(image: image)
20
+ var videoOutput = AVCaptureVideoDataOutput()
21
+
22
+ var images:[UIImage] = []
23
+
24
+ var count: Int = 0
25
+
26
+ override func viewDidLoad() {
27
+ super.viewDidLoad()
18
28
 
29
+ if session.isRunning {
30
+ return
31
+ }
32
+
33
+ images.removeAll()
34
+
35
+ setupInputOutput()
36
+
19
- previewView.image = image
37
+ self.session.startRunning()
20
38
  }
21
39
 
40
+ override func didReceiveMemoryWarning() {
41
+ super.didReceiveMemoryWarning()
42
+ }
43
+
44
+ func setupInputOutput() {
45
+
46
+ session.sessionPreset = AVCaptureSession.Preset.medium
47
+
48
+ do {
49
+ let device = AVCaptureDevice.default(
50
+ AVCaptureDevice.DeviceType.builtInWideAngleCamera,
51
+ for: AVMediaType.video,
52
+ position: AVCaptureDevice.Position.back
53
+ )
54
+ device?.activeVideoMinFrameDuration = CMTimeMake(1, 30)
55
+
56
+ let input = try! AVCaptureDeviceInput(device: device!)
57
+ if session.canAddInput(input) {
58
+ session.addInput(input)
59
+ } else {
60
+ print("Can't add input to session")
61
+ return
62
+ }
63
+ } catch let error as NSError {
64
+ print("no camera (error)")
65
+ return
66
+ }
67
+
68
+ videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable : Int(kCVPixelFormatType_32BGRA)] as! [String : Any]
69
+ videoOutput.alwaysDiscardsLateVideoFrames = true
22
- func imageFromSampleBuffer(sampleBuffer :CMSampleBuffer) -> UIImage {
70
+ videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main)
71
+ if session.canAddOutput(videoOutput) {
72
+ session.addOutput(videoOutput)
73
+ } else {
74
+ print("Can't add output to session")
75
+ return
76
+ }
77
+ }
78
+
79
+ func setPreviewLayer() {
80
+ let previewLayer = AVCaptureVideoPreviewLayer(session: session)
81
+ guard let videoLayer: AVCaptureVideoPreviewLayer = previewLayer else {
82
+ print("Can't create preview layer.")
83
+ return
84
+ }
85
+
86
+ videoLayer.frame = previewView.bounds
87
+ videoLayer.masksToBounds = true
88
+ videoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
89
+ previewView.layer.addSublayer(videoLayer)
90
+ }
91
+
92
+ func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
23
93
  let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
24
-
25
94
  // イメージバッファのロック
26
95
  CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
27
96
 
97
+ self.imageFromSampleBuffer(sampleBuffer: sampleBuffer)
98
+
99
+ CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
100
+
101
+ DispatchQueue.main.async {
102
+ self.previewView.image = image
103
+ }
104
+ }
105
+
106
+ func imageFromSampleBuffer(sampleBuffer :CMSampleBuffer) -> UIImage {
107
+ let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
108
+
28
109
  // 画像情報を取得
29
110
  let base = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0)!
30
111
  let bytesPerRow = UInt(CVPixelBufferGetBytesPerRow(imageBuffer))
@@ -39,43 +120,27 @@
39
120
 
40
121
  // 画像作成
41
122
  let imageRef = newContext.makeImage()!
42
- // ここのreturnでUIImageを返すと、画像がちゃんと表示される (1)
43
- //return UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.right)
44
123
 
124
+ // (1)ここでimgを返すとキャプチャした画像が正常に表示される
45
- CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
125
+ //let img = UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.right)
46
- var img = getByteArrayFromImage(imageRef: imageRef)
47
- return img
126
+ //return img
48
- }
49
-
50
- func getByteArrayFromImage(imageRef: CGImage) -> UIImage {
51
- let editedimage:UIImage
52
127
 
53
- let width_n :Int = Int((imageRef.width))
54
- let height_n :Int = Int((imageRef.height))
55
-
56
128
  let data = imageRef.dataProvider!.data
57
129
  let length = CFDataGetLength(data)
58
130
  var rawData = [UInt8](repeating: 0, count: length)
131
+ CFDataGetBytes(data, CFRange(location: 0, length: length), &rawData)
59
132
 
60
- CFDataGetBytes(data, CFRange(location: 0, length: length), &rawData)
61
- //for (index, _) in rawData.enumerated() {
62
- // rawData[index] = 255
63
- //}
64
-
65
- let provider = CGDataProvider(dataInfo: nil,data: rawData, size: length,releaseData: releaseData)
133
+ let provider = CGDataProvider(dataInfo: nil,data: &rawData, size: length,releaseData: releaseData)
66
- let colorSpaceRef = imageRef.colorSpace
67
- let bitmapInfo_n = imageRef.bitmapInfo
68
- let bitsPerComponent:Int = imageRef.bitsPerComponent
69
134
  let bitsPerPixel = imageRef.bitsPerPixel
70
- let bytesPerRow_n = imageRef.bytesPerRow
71
- let cgImage = CGImage(width: width_n, height: height_n, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow:bytesPerRow_n, space: colorSpaceRef!, bitmapInfo: bitmapInfo_n, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent)
72
-
73
- editedimage = UIImage(cgImage:cgImage!, scale:1.0, orientation:UIImageOrientation.right)
135
+ let cgImage = CGImage(width: Int(width), height: Int(height), bitsPerComponent: bitsPerCompornent, bitsPerPixel: bitsPerPixel, bytesPerRow:Int(bytesPerRow), space: colorSpace, bitmapInfo: bitmapInfo, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent)
74
136
 
137
+ let editedimage = UIImage(cgImage:cgImage!, scale:1.0, orientation:UIImageOrientation.right)
138
+
75
- // (2) editedimageには画像データ常に入ってい
139
+ // (2)ここで返すと画像が常に
76
140
  return editedimage
77
-
78
141
  }
142
+ }
143
+
79
144
  ```
80
145
 
81
146
  ### 補足情報(FW/ツールのバージョンなど)

4

コメントアウト

2018/08/03 10:58

投稿

nobu09
nobu09

スコア35

title CHANGED
File without changes
body CHANGED
@@ -58,9 +58,9 @@
58
58
  var rawData = [UInt8](repeating: 0, count: length)
59
59
 
60
60
  CFDataGetBytes(data, CFRange(location: 0, length: length), &rawData)
61
- for (index, _) in rawData.enumerated() {
61
+ //for (index, _) in rawData.enumerated() {
62
- rawData[index] = 255
62
+ // rawData[index] = 255
63
- }
63
+ //}
64
64
 
65
65
  let provider = CGDataProvider(dataInfo: nil,data: rawData, size: length,releaseData: releaseData)
66
66
  let colorSpaceRef = imageRef.colorSpace

3

発生した現象を編集

2018/08/03 05:58

投稿

nobu09
nobu09

スコア35

title CHANGED
File without changes
body CHANGED
@@ -3,8 +3,12 @@
3
3
 
4
4
  ### 発生している問題・エラーメッセージ[編集]
5
5
  キャプチャ画像→ピクセルデータ配列→何かしらの処理→UIImageという処理をしたいのですが、
6
- メソッド内で作成したUIImagを返り値で別の変数に代入するとの画像が壊れています。
6
+ メソッド内で作成したUIImagを返り値で別の変数に代入した際タイミングによって代入先の画像が壊れています。
7
7
 
8
+ 具体的には、以下のソースコード内の
9
+ (1)の部分でreturnした場合は、正常に画像が渡され表示できます。
10
+ (2)の部分でreturnした場合は、異常な画像データが渡されてしまいます。
11
+
8
12
  ### 該当のソースコード[編集]
9
13
 
10
14
  ```swift
@@ -35,6 +39,9 @@
35
39
 
36
40
  // 画像作成
37
41
  let imageRef = newContext.makeImage()!
42
+ // ここのreturnでUIImageを返すと、画像がちゃんと表示される (1)
43
+ //return UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.right)
44
+
38
45
  CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
39
46
  var img = getByteArrayFromImage(imageRef: imageRef)
40
47
  return img
@@ -64,7 +71,8 @@
64
71
  let cgImage = CGImage(width: width_n, height: height_n, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow:bytesPerRow_n, space: colorSpaceRef!, bitmapInfo: bitmapInfo_n, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent)
65
72
 
66
73
  editedimage = UIImage(cgImage:cgImage!, scale:1.0, orientation:UIImageOrientation.right)
74
+
67
-
75
+ // (2) editedimageには画像データが正常に入っている
68
76
  return editedimage
69
77
 
70
78
  }

2

swiftのバージョンの修正

2018/08/02 05:51

投稿

nobu09
nobu09

スコア35

title CHANGED
File without changes
body CHANGED
@@ -73,4 +73,4 @@
73
73
  ### 補足情報(FW/ツールのバージョンなど)
74
74
 
75
75
  xcode Version 9.4.1
76
- Swift3.0
76
+ Swift4.0

1

ソースコードの編集

2018/08/02 03:30

投稿

nobu09
nobu09

スコア35

title CHANGED
@@ -1,1 +1,1 @@
1
- [Swift3]カメラ画像→ピクセルデータ配列→UIImageと順番に変換したい
1
+ [Swift3]カメラ画像→ピクセルデータ配列→UIImageと順番に変換したい[編集]
body CHANGED
@@ -1,20 +1,21 @@
1
1
  ### 前提・実現したいこと
2
2
  カメラからのキャプチャ画像に何かしらの操作をして、その画像をUIImageViewで表示したいです。
3
3
 
4
- ### 発生している問題・エラーメッセージ
4
+ ### 発生している問題・エラーメッセージ[編集]
5
5
  キャプチャ画像→ピクセルデータ配列→何かしらの処理→UIImageという処理をしたいのですが、
6
- 何かしらの処理が実施されない状態、キャプチャした画像がそのまま表示されてう状態です。
6
+ メソッド内作成したUIImagを返り値で別の変数に代入すると、その画像がれてます。
7
7
 
8
- ### 該当のソースコード
8
+ ### 該当のソースコード[編集]
9
9
 
10
10
  ```swift
11
- func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
11
+ func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
12
- let image = imageFromSampleBuffer(sampleBuffer: sampleBuffer)
12
+ let image = self.imageFromSampleBuffer(sampleBuffer: sampleBuffer)
13
-
13
+ // addImage(image: image)
14
+
14
15
  previewView.image = image
15
16
  }
16
17
 
17
- func imageFromSampleBuffer(sampleBuffer :CMSampleBuffer) -> UIImage {
18
+ func imageFromSampleBuffer(sampleBuffer :CMSampleBuffer) -> UIImage {
18
19
  let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
19
20
 
20
21
  // イメージバッファのロック
@@ -34,39 +35,38 @@
34
35
 
35
36
  // 画像作成
36
37
  let imageRef = newContext.makeImage()!
38
+ CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
39
+ var img = getByteArrayFromImage(imageRef: imageRef)
40
+ return img
41
+ }
42
+
37
- let image = UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.right)
43
+ func getByteArrayFromImage(imageRef: CGImage) -> UIImage {
44
+ let editedimage:UIImage
38
45
 
46
+ let width_n :Int = Int((imageRef.width))
47
+ let height_n :Int = Int((imageRef.height))
48
+
39
- let data = image.cgImage?.dataProvider?.data
49
+ let data = imageRef.dataProvider!.data
40
50
  let length = CFDataGetLength(data)
41
51
  var rawData = [UInt8](repeating: 0, count: length)
42
52
 
43
53
  CFDataGetBytes(data, CFRange(location: 0, length: length), &rawData)
44
-
45
- // ピクセルデータrawDataの値操作
46
-      // ここで画素データを使用して何かしらの処理をしたい
47
-      // テストとして全値を0にする
48
54
  for (index, _) in rawData.enumerated() {
49
- rawData[index] = 0
55
+ rawData[index] = 255
50
56
  }
51
57
 
52
- let data = CGDataProvider(dataInfo: nil, data: rawData, size: length) { _,_,_ in }
53
- .flatMap {
54
- CGImage(width: Int(width),
55
- height: Int(height),
56
- bitsPerComponent: 32,
57
- bitsPerPixel: Int(bytesPerRow / 32),
58
- bytesPerRow: Int(width * bytesPerRow),
59
- space: CGColorSpaceCreateDeviceRGB(),
60
- bitmapInfo: [],
61
- provider: $0,
62
- decode: nil,
63
- shouldInterpolate: false,
64
- intent: .defaultIntent)
65
- }
66
- CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
58
+ let provider = CGDataProvider(dataInfo: nil,data: rawData, size: length,releaseData: releaseData)
59
+ let colorSpaceRef = imageRef.colorSpace
60
+ let bitmapInfo_n = imageRef.bitmapInfo
61
+ let bitsPerComponent:Int = imageRef.bitsPerComponent
62
+ let bitsPerPixel = imageRef.bitsPerPixel
63
+ let bytesPerRow_n = imageRef.bytesPerRow
64
+ let cgImage = CGImage(width: width_n, height: height_n, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow:bytesPerRow_n, space: colorSpaceRef!, bitmapInfo: bitmapInfo_n, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent)
67
65
 
68
- return UIImage(cgImage: d!)
66
+ editedimage = UIImage(cgImage:cgImage!, scale:1.0, orientation:UIImageOrientation.right)
69
67
 
68
+ return editedimage
69
+
70
70
  }
71
71
  ```
72
72