Skip to content

Commit

Permalink
feat: Add rotation to iOS (#548)
Browse files Browse the repository at this point in the history
  • Loading branch information
juanmartin8a authored and fbernaly committed Apr 15, 2024
1 parent 2d3b4f8 commit 315a7d6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/example/lib/vision_detector_views/camera_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ class _CameraViewState extends State<CameraView> {
rotation: rotation, // used only in Android
format: format, // used only in iOS
bytesPerRow: plane.bytesPerRow, // used only in iOS
cameraLensDirection: InputImageCameraLensDirectionValue.fromRawValue(
camera.lensDirection.index) ??
InputImageCameraLensDirection.front,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ + (MLKVisionImage *)bytesToVisionImage:(NSDictionary *)imageData {
NSNumber *height = metadata[@"height"];
NSNumber *rawFormat = metadata[@"image_format"];
NSNumber *bytesPerRow = metadata[@"bytes_per_row"];
int rotation = [metadata[@"rotation"] intValue];
int cameraLensDirection = [metadata[@"camera_lens_direction"] intValue];
UIImageOrientation imageOrientation = [self imageOrientationFromRotation:rotation cameraLensDirection:cameraLensDirection];
CVPixelBufferRef pxBuffer = [self bytesToPixelBuffer:width.unsignedLongValue
height:height.unsignedLongValue
format:FOUR_CHAR_CODE(rawFormat.unsignedIntValue)
baseAddress:(void *)imageBytes.bytes
bytesPerRow:bytesPerRow.unsignedLongValue];
return [self pixelBufferToVisionImage:pxBuffer];
MLKVisionImage *image = [self pixelBufferToVisionImage:pxBuffer];
image.orientation = imageOrientation;
return image;
}

+ (CVPixelBufferRef)bytesToPixelBuffer:(size_t)width
Expand Down Expand Up @@ -66,4 +71,21 @@ + (MLKVisionImage *)pixelBufferToVisionImage:(CVPixelBufferRef)pixelBufferRef {
return [[MLKVisionImage alloc] initWithImage:uiImage];
}

+ (UIImageOrientation)imageOrientationFromRotation:(int)rotation cameraLensDirection:(int)cameraLensDirection {
switch (rotation) {
case 90:
return cameraLensDirection == 0 ? UIImageOrientationRight // Rotates the image 270 degrees to the left
: UIImageOrientationRightMirrored; // Rotates the image 270 degrees to the left (image is mirrored)
case 180:
return cameraLensDirection == 0 ? UIImageOrientationDown // Rotates the image 180 degrees to the left
: UIImageOrientationDownMirrored; // Rotates the image 180 degrees to the left (image is mirrored)
case 270:
return cameraLensDirection == 0 ? UIImageOrientationLeft // Rotates the image 90 degrees to the left
: UIImageOrientationLeftMirrored; // Rotates the image 90 degrees to the left (image is mirrored)
default:
return cameraLensDirection == 0 ? UIImageOrientationUp // Rotates 0 degreees
: UIImageOrientationUpMirrored; // Rotates the image 0 degrees (image is mirrored)
}
}

@end
37 changes: 35 additions & 2 deletions packages/google_mlkit_commons/lib/src/input_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ class InputImageMetadata {
final Size size;

/// Image rotation degree.
///
/// Not used on iOS.
final InputImageRotation rotation;

// Camera lens direction.
///
/// Not used on Android.
final InputImageCameraLensDirection cameraLensDirection;

/// Format of the input image.
///
/// Not used on Android.
Expand All @@ -76,6 +79,7 @@ class InputImageMetadata {
required this.rotation,
required this.format,
required this.bytesPerRow,
required this.cameraLensDirection,
});

/// Returns a json representation of an instance of [InputImageMetadata].
Expand All @@ -85,6 +89,7 @@ class InputImageMetadata {
'rotation': rotation.rawValue,
'image_format': format.rawValue,
'bytes_per_row': bytesPerRow,
'camera_lens_direction': cameraLensDirection.rawValue,
};
}

Expand Down Expand Up @@ -155,3 +160,31 @@ extension InputImageFormatValue on InputImageFormat {
}
}
}

/// The camera lens direction to be specified
///
/// Not used on Android.
enum InputImageCameraLensDirection {
front,
back,
}

extension InputImageCameraLensDirectionValue on InputImageCameraLensDirection {
int get rawValue {
switch (this) {
case InputImageCameraLensDirection.back:
return 0;
case InputImageCameraLensDirection.front:
return 1;
}
}

static InputImageCameraLensDirection? fromRawValue(int rawValue) {
try {
return InputImageCameraLensDirection.values
.firstWhere((element) => element.rawValue == rawValue);
} catch (_) {
return null;
}
}
}

0 comments on commit 315a7d6

Please sign in to comment.