回答編集履歴

2

追記1

2018/08/03 09:19

投稿

u39ueda
u39ueda

スコア950

test CHANGED
@@ -5,3 +5,121 @@
5
5
 
6
6
 
7
7
  もしメインスレッドから呼んでいた場合は `getByteArrayFromImage()` の実行を`CVPixelBufferUnlockBaseAddress()` の前に移動してみてはどうでしょうか。
8
+
9
+
10
+
11
+ #### 追記
12
+
13
+
14
+
15
+ 実際に試してみましたが以下のような問題があるようです。
16
+
17
+
18
+
19
+ - メインスレッドでfor文をぶん回しているせいで処理に時間がかかっている
20
+
21
+ →バックグラウンドスレッドで実行させればマシになる(それでもカクカクだけど)
22
+
23
+ →for文をコメントアウトするならそのままでもOK
24
+
25
+ - 真っ白に表示されるのはforで真っ白に塗り潰しているから
26
+
27
+ →コメントアウト
28
+
29
+ - rawDataが画像として使っている間に解放されてしまってクラッシュする
30
+
31
+ 今クラッシュしていないのはよくわからない。CPU使用率100%だから?
32
+
33
+ →UnsafeMutablePointer.allocate(capacity:)を使ってスコープを抜けても解放されないようにする
34
+
35
+
36
+
37
+ rawDataを解放されないようにするのと、for文をコメントアウトすれば動きました。
38
+
39
+ 変更前のコードはコメントアウトしてありますので見比べてください。
40
+
41
+
42
+
43
+ ```Swift
44
+
45
+ func getByteArrayFromImage(imageRef: CGImage) -> UIImage {
46
+
47
+ let editedimage:UIImage
48
+
49
+
50
+
51
+ let width_n :Int = Int((imageRef.width))
52
+
53
+ let height_n :Int = Int((imageRef.height))
54
+
55
+
56
+
57
+ let data = imageRef.dataProvider!.data
58
+
59
+ let length = CFDataGetLength(data)
60
+
61
+ // var rawData = [UInt8](repeating: 0, count: length)
62
+
63
+ let rawData = UnsafeMutablePointer<UInt8>.allocate(capacity: length)
64
+
65
+
66
+
67
+ // CFDataGetBytes(data, CFRange(location: 0, length: length), &rawData)
68
+
69
+ CFDataGetBytes(data, CFRange(location: 0, length: length), rawData)
70
+
71
+ // for文で回すならUnsafeMutableBufferPointerを使う
72
+
73
+ let rawDataBuffer = UnsafeMutableBufferPointer<UInt8>(start: rawData, count: length)
74
+
75
+ //for (index, _) in rawData.enumerated() {
76
+
77
+ // rawData[index] = 255
78
+
79
+ //}
80
+
81
+
82
+
83
+ // let provider = CGDataProvider(dataInfo: nil, data: &rawData, size: length,releaseData: releaseData)
84
+
85
+ let provider = CGDataProvider(dataInfo: nil, data: rawData, size: length,releaseData: releaseData)
86
+
87
+ let colorSpaceRef = imageRef.colorSpace
88
+
89
+ let bitmapInfo_n = imageRef.bitmapInfo
90
+
91
+ let bitsPerComponent:Int = imageRef.bitsPerComponent
92
+
93
+ let bitsPerPixel = imageRef.bitsPerPixel
94
+
95
+ let bytesPerRow_n = imageRef.bytesPerRow
96
+
97
+ 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)
98
+
99
+
100
+
101
+ editedimage = UIImage(cgImage:cgImage!, scale:1.0, orientation:UIImageOrientation.right)
102
+
103
+
104
+
105
+ // (2) editedimageには画像データが正常に入っている
106
+
107
+ return editedimage
108
+
109
+
110
+
111
+ }
112
+
113
+
114
+
115
+ // releaseDataの定義が見当たらなかったので適当に実装しました
116
+
117
+ func releaseData(info: UnsafeMutableRawPointer?, data: UnsafeRawPointer, length: Int) {
118
+
119
+ print(#function, info ?? "nil", data, length)
120
+
121
+ data.deallocate()
122
+
123
+ }
124
+
125
+ ```

1

他の可能性を追記

2018/08/03 09:19

投稿

u39ueda
u39ueda

スコア950

test CHANGED
@@ -1,3 +1,7 @@
1
1
  `func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)` がメインスレッド以外から呼ばれていませんか?
2
2
 
3
3
  `sampleBufferCallbackQueue` にセットされているDispatchQueueから呼ばれるようです。
4
+
5
+
6
+
7
+ もしメインスレッドから呼んでいた場合は `getByteArrayFromImage()` の実行を`CVPixelBufferUnlockBaseAddress()` の前に移動してみてはどうでしょうか。