react-native-yolo 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import NitroModules
|
|
3
3
|
import VisionCamera
|
|
4
|
+
import CoreVideo
|
|
4
5
|
|
|
5
6
|
public enum FrameJpegConverter {
|
|
6
7
|
private static let tag = "YOLO_TAG_FrameJpegConverter"
|
|
7
|
-
|
|
8
|
+
|
|
8
9
|
public static func toJpegBytes(frame: any HybridFrameSpec, quality: Int = 80) -> [UInt8] {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
10
|
+
do {
|
|
11
|
+
let nativeBuffer = try frame.getNativeBuffer()
|
|
12
|
+
|
|
13
|
+
guard let rawPointer = UnsafeRawPointer(bitPattern: UInt(nativeBuffer.pointer)) else {
|
|
14
|
+
NSLog("[%@]: ❌ Failed to get native buffer pointer", tag)
|
|
15
|
+
return []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let pixelBuffer = Unmanaged<CVPixelBuffer>
|
|
19
|
+
.fromOpaque(rawPointer)
|
|
20
|
+
.takeUnretainedValue()
|
|
21
|
+
|
|
22
|
+
let jpegBytes = Nv12JpegEncoder.encode(
|
|
23
|
+
pixelBuffer: pixelBuffer,
|
|
24
|
+
quality: quality
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if jpegBytes.isEmpty {
|
|
28
|
+
NSLog("[%@]: ❌ Failed to encode pixelBuffer to JPEG bytes", tag)
|
|
29
|
+
return []
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return BitmapOrientationFixer.fix(
|
|
33
|
+
jpegBytes: jpegBytes,
|
|
34
|
+
frame: frame,
|
|
35
|
+
quality: quality
|
|
36
|
+
)
|
|
37
|
+
} catch {
|
|
38
|
+
NSLog("[%@]: ❌ Failed to convert frame to JPEG: %@", tag, "\(error)")
|
|
31
39
|
return []
|
|
32
40
|
}
|
|
33
|
-
|
|
34
|
-
// 4. Redessin de sécurité via UIGraphicsImageRenderer pour fixer définitivement les pixels
|
|
35
|
-
return BitmapOrientationFixer.fix(
|
|
36
|
-
jpegBytes: jpegBytes,
|
|
37
|
-
frame: frame,
|
|
38
|
-
quality: quality
|
|
39
|
-
)
|
|
40
41
|
}
|
|
41
|
-
}
|
|
42
|
+
}
|
|
@@ -1,58 +1,32 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import CoreImage
|
|
3
|
-
import
|
|
3
|
+
import CoreVideo
|
|
4
|
+
import ImageIO
|
|
4
5
|
|
|
5
6
|
public enum Nv12JpegEncoder {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
private static let ciContext = CIContext(options: [
|
|
8
|
+
CIContextOption.useSoftwareRenderer: false
|
|
9
|
+
])
|
|
10
|
+
|
|
9
11
|
public static func encode(
|
|
10
|
-
|
|
11
|
-
width: Int,
|
|
12
|
-
height: Int,
|
|
12
|
+
pixelBuffer: CVPixelBuffer,
|
|
13
13
|
quality: Int
|
|
14
14
|
) -> [UInt8] {
|
|
15
|
-
|
|
16
|
-
// 1. Convertir la qualité (0-100 sur Android) en CGFloat (0.0-1.0 sur iOS)
|
|
17
15
|
let compressionQuality = CGFloat(max(0, min(quality, 100))) / 100.0
|
|
18
|
-
|
|
19
|
-
let
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// 3. Spécifier le format de couleur NV12 pour CoreImage (kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)
|
|
29
|
-
let imageOptions: [CIImageOption: Any] = [
|
|
30
|
-
.colorSpace: CGColorSpaceCreateDeviceRGB()
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
// On indique à CoreImage la structure exacte du NV12 (Plan 0: Y, Plan 1: UV entrelacé)
|
|
34
|
-
guard let ciImage = CIImage(
|
|
35
|
-
imageWithFormat: Int32(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
|
|
36
|
-
size: CGSize(width: width, height: height),
|
|
37
|
-
data: rawData,
|
|
38
|
-
rowBytes: width,
|
|
39
|
-
options: imageOptions
|
|
16
|
+
|
|
17
|
+
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
|
|
18
|
+
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
19
|
+
|
|
20
|
+
guard let jpegData = ciContext.jpegRepresentation(
|
|
21
|
+
of: ciImage,
|
|
22
|
+
colorSpace: colorSpace,
|
|
23
|
+
options: [
|
|
24
|
+
kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption: compressionQuality
|
|
25
|
+
]
|
|
40
26
|
) else {
|
|
41
27
|
return []
|
|
42
28
|
}
|
|
43
|
-
|
|
44
|
-
// 4. Rendu de l'image GPU vers une structure d'image CoreGraphics
|
|
45
|
-
guard let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent) else {
|
|
46
|
-
return []
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 5. Conversion en UIImage puis compression matérielle en JPEG
|
|
50
|
-
let uiImage = UIImage(cgImage: cgImage)
|
|
51
|
-
guard let jpegData = uiImage.jpegData(compressionQuality: compressionQuality) else {
|
|
52
|
-
return []
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 6. Retourner le tableau d'octets natif [UInt8] requis par votre modèle
|
|
29
|
+
|
|
56
30
|
return [UInt8](jpegData)
|
|
57
31
|
}
|
|
58
|
-
}
|
|
32
|
+
}
|