This repository has been archived by the owner on Dec 5, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
camera_image.dart
145 lines (124 loc) · 4.88 KB
/
camera_image.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of 'camera.dart';
/// A single color plane of image data.
///
/// The number and meaning of the planes in an image are determined by the
/// format of the Image.
class Plane {
Plane._fromPlatformData(Map<dynamic, dynamic> data)
: bytes = data['bytes'],
bytesPerPixel = data['bytesPerPixel'],
bytesPerRow = data['bytesPerRow'],
height = data['height'],
width = data['width'];
/// Bytes representing this plane.
final Uint8List bytes;
/// The distance between adjacent pixel samples on Android, in bytes.
///
/// Will be `null` on iOS.
final int bytesPerPixel;
/// The row stride for this color plane, in bytes.
final int bytesPerRow;
/// Height of the pixel buffer on iOS.
///
/// Will be `null` on Android
final int height;
/// Width of the pixel buffer on iOS.
///
/// Will be `null` on Android.
final int width;
}
// TODO:(bmparr) Turn [ImageFormatGroup] to a class with int values.
/// Group of image formats that are comparable across Android and iOS platforms.
enum ImageFormatGroup {
/// The image format does not fit into any specific group.
unknown,
/// Multi-plane YUV 420 format.
///
/// This format is a generic YCbCr format, capable of describing any 4:2:0
/// chroma-subsampled planar or semiplanar buffer (but not fully interleaved),
/// with 8 bits per color sample.
///
/// On Android, this is `android.graphics.ImageFormat.YUV_420_888`. See
/// https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888
///
/// On iOS, this is `kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange`. See
/// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_420ypcbcr8biplanarvideorange?language=objc
yuv420,
/// 32-bit BGRA.
///
/// On iOS, this is `kCVPixelFormatType_32BGRA`. See
/// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_32bgra?language=objc
bgra8888,
}
/// Describes how pixels are represented in an image.
class ImageFormat {
ImageFormat._fromPlatformData(this.raw) : group = _asImageFormatGroup(raw);
/// Describes the format group the raw image format falls into.
final ImageFormatGroup group;
/// Raw version of the format from the Android or iOS platform.
///
/// On Android, this is an `int` from class `android.graphics.ImageFormat`. See
/// https://developer.android.com/reference/android/graphics/ImageFormat
///
/// On iOS, this is a `FourCharCode` constant from Pixel Format Identifiers.
/// See https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers?language=objc
final dynamic raw;
}
ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) {
if (defaultTargetPlatform == TargetPlatform.android) {
// android.graphics.ImageFormat.YUV_420_888
if (rawFormat == 35) {
return ImageFormatGroup.yuv420;
}
}
if (defaultTargetPlatform == TargetPlatform.iOS) {
switch (rawFormat) {
// kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
case 875704438:
return ImageFormatGroup.yuv420;
// kCVPixelFormatType_32BGRA
case 1111970369:
return ImageFormatGroup.bgra8888;
}
}
return ImageFormatGroup.unknown;
}
/// A single complete image buffer from the platform camera.
///
/// This class allows for direct application access to the pixel data of an
/// Image through one or more [Uint8List]. Each buffer is encapsulated in a
/// [Plane] that describes the layout of the pixel data in that plane. The
/// [CameraImage] is not directly usable as a UI resource.
///
/// Although not all image formats are planar on iOS, we treat 1-dimensional
/// images as single planar images.
class CameraImage {
CameraImage._fromPlatformData(Map<dynamic, dynamic> data)
: format = ImageFormat._fromPlatformData(data['format']),
height = data['height'],
width = data['width'],
planes = List<Plane>.unmodifiable(data['planes']
.map((dynamic planeData) => Plane._fromPlatformData(planeData)));
/// Format of the image provided.
///
/// Determines the number of planes needed to represent the image, and
/// the general layout of the pixel data in each [Uint8List].
final ImageFormat format;
/// Height of the image in pixels.
///
/// For formats where some color channels are subsampled, this is the height
/// of the largest-resolution plane.
final int height;
/// Width of the image in pixels.
///
/// For formats where some color channels are subsampled, this is the width
/// of the largest-resolution plane.
final int width;
/// The pixels planes for this image.
///
/// The number of planes is determined by the format of the image.
final List<Plane> planes;
}