Merge pull request #211 from rpopovici/master

set capture quality on android and iOS
This commit is contained in:
Zack Story 2016-03-21 12:51:26 -07:00
commit bdb48c3956
8 changed files with 177 additions and 3 deletions

View File

@ -33,6 +33,10 @@ function convertStringProps(props) {
newProps.type = Camera.constants.Type[props.type];
}
if (typeof props.captureQuality === 'string') {
newProps.captureQuality = Camera.constants.CaptureQuality[props.captureQuality];
}
return newProps;
}
@ -44,6 +48,7 @@ export default class Camera extends Component {
Type: CameraManager.Type,
CaptureMode: CameraManager.CaptureMode,
CaptureTarget: CameraManager.CaptureTarget,
CaptureQuality: CameraManager.CaptureQuality,
Orientation: CameraManager.Orientation,
FlashMode: CameraManager.FlashMode,
TorchMode: CameraManager.TorchMode
@ -60,6 +65,10 @@ export default class Camera extends Component {
PropTypes.string,
PropTypes.number
]),
captureQuality: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
captureTarget: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
@ -94,6 +103,7 @@ export default class Camera extends Component {
captureAudio: true,
captureMode: CameraManager.CaptureMode.still,
captureTarget: CameraManager.CaptureTarget.cameraRoll,
captureQuality: CameraManager.CaptureQuality.high,
defaultOnFocusComponent: true,
flashMode: CameraManager.FlashMode.off,
torchMode: CameraManager.TorchMode.off
@ -143,6 +153,7 @@ export default class Camera extends Component {
audio: props.captureAudio,
mode: props.captureMode,
target: props.captureTarget,
quality: props.captureQuality,
type: props.type,
title: '',
description: '',

View File

@ -139,6 +139,11 @@ Values: `Camera.constants.CaptureTarget.cameraRoll` (default), `Camera.constants
This property allows you to specify the target output of the captured image data. By default the image binary is sent back as a base 64 encoded string. The disk output has been shown to improve capture response time, so that is the recommended value.
#### `iOS` `captureQuality`
Values: `Camera.constants.CaptureQuality.high` or `"high"` (default), `Camera.constants.CaptureQuality.medium` or `"medium"`, `Camera.constants.CaptureQuality.low` or `"low"`
This property allows you to specify the quality output of the captured image or video. By default the quality is set to high.
#### `type`

View File

@ -59,6 +59,79 @@ public class RCTCamera {
return cameraInfo.previewHeight;
}
public Camera.Size getBestPreviewSize(int type, int width, int height)
{
Camera camera = _cameras.get(type);
Camera.Size result = null;
if(camera == null) {
return null;
}
Camera.Parameters params = camera.getParameters();
for (Camera.Size size : params.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return result;
}
public Camera.Size getBestPictureSize(int type, int width, int height)
{
Camera camera = _cameras.get(type);
Camera.Size result = null;
if(camera == null) {
return null;
}
Camera.Parameters params = camera.getParameters();
for (Camera.Size size : params.getSupportedPictureSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return result;
}
public Camera.Size getSmallestPictureSize(int type)
{
Camera camera = _cameras.get(type);
Camera.Size result = null;
if(camera == null) {
return null;
}
Camera.Parameters params = camera.getParameters();
for (Camera.Size size : params.getSupportedPictureSizes()) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea < resultArea) {
result = size;
}
}
}
return result;
}
public void setOrientation(int orientation) {
if (_orientation == orientation) {
return;
@ -74,6 +147,33 @@ public class RCTCamera {
adjustPreviewLayout(RCTCameraModule.RCT_CAMERA_TYPE_BACK);
}
public void setCaptureQuality(int cameraType, String captureQuality) {
Camera camera = _cameras.get(cameraType);
if (null == camera) {
return;
}
Camera.Parameters parameters = camera.getParameters();
Camera.Size pictureSize = null;
switch (captureQuality) {
case "low":
pictureSize = getSmallestPictureSize(cameraType); // select the lowest res
break;
case "medium":
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
pictureSize = sizes.get(sizes.size() / 2);
break;
case "high":
pictureSize = getBestPictureSize(cameraType, Integer.MAX_VALUE, Integer.MAX_VALUE); // select the highest res
break;
}
if (pictureSize != null) {
parameters.setPictureSize(pictureSize.width, pictureSize.height);
camera.setParameters(parameters);
}
}
public void setTorchMode(int cameraType, int torchMode) {
Camera camera = _cameras.get(cameraType);
if (null == camera) {
@ -150,8 +250,10 @@ public class RCTCamera {
parameters.setRotation(cameraInfo.rotation);
// set preview size
int width = parameters.getSupportedPreviewSizes().get(0).width;
int height = parameters.getSupportedPreviewSizes().get(0).height;
// defaults to highest resolution available
Camera.Size optimalPreviewSize = getBestPreviewSize(type, Integer.MAX_VALUE, Integer.MAX_VALUE);
int width = optimalPreviewSize.width;
int height = optimalPreviewSize.height;
parameters.setPreviewSize(width, height);
try {

View File

@ -69,6 +69,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule {
{
put("Aspect", getAspectConstants());
put("Type", getTypeConstants());
put("CaptureQuality", getCaptureQualityConstants());
put("CaptureMode", getCaptureModeConstants());
put("CaptureTarget", getCaptureTargetConstants());
put("Orientation", getOrientationConstants());
@ -95,6 +96,16 @@ public class RCTCameraModule extends ReactContextBaseJavaModule {
});
}
private Map<String, Object> getCaptureQualityConstants() {
return Collections.unmodifiableMap(new HashMap<String, Object>() {
{
put("low", "low");
put("medium", "medium");
put("high", "high");
}
});
}
private Map<String, Object> getCaptureModeConstants() {
return Collections.unmodifiableMap(new HashMap<String, Object>() {
{
@ -156,6 +167,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule {
promise.reject("No camera found.");
return;
}
RCTCamera.getInstance().setCaptureQuality(options.getInt("type"), options.getString("quality"));
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {

View File

@ -17,6 +17,7 @@ public class RCTCameraView extends ViewGroup {
private RCTCameraViewFinder _viewFinder = null;
private int _actualDeviceOrientation = -1;
private int _aspect = RCTCameraModule.RCT_CAMERA_ASPECT_FIT;
private String _captureQuality = "high";
private int _torchMode = -1;
private int _flashMode = -1;
@ -66,6 +67,13 @@ public class RCTCameraView extends ViewGroup {
}
}
public void setCaptureQuality(String captureQuality) {
this._captureQuality = captureQuality;
if (this._viewFinder != null) {
this._viewFinder.setCaptureQuality(captureQuality);
}
}
public void setTorchMode(int torchMode) {
this._torchMode = torchMode;
if (this._viewFinder != null) {

View File

@ -65,6 +65,10 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
}).start();
}
public void setCaptureQuality(String captureQuality) {
RCTCamera.getInstance().setCaptureQuality(_cameraType, captureQuality);
}
public void setTorchMode(int torchMode) {
RCTCamera.getInstance().setTorchMode(_cameraType, torchMode);
}
@ -91,10 +95,16 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText
try {
_camera = RCTCamera.getInstance().acquireCameraInstance(_cameraType);
Camera.Parameters parameters = _camera.getParameters();
// set autofocus
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
// set picture size
// defaults to max available size
Camera.Size optimalPictureSize = RCTCamera.getInstance().getBestPictureSize(_cameraType, Integer.MAX_VALUE, Integer.MAX_VALUE);
parameters.setPictureSize(optimalPictureSize.width, optimalPictureSize.height);
_camera.setParameters(parameters);
_camera.setPreviewTexture(_surfaceTexture);
_camera.startPreview();

View File

@ -37,6 +37,11 @@ public class RCTCameraViewManager extends ViewGroupManager<RCTCameraView> {
view.setCameraType(type);
}
@ReactProp(name = "captureQuality")
public void setCaptureQuality(RCTCameraView view, String captureQuality) {
view.setCaptureQuality(captureQuality);
}
@ReactProp(name = "torchMode")
public void setTorchMode(RCTCameraView view, int torchMode) {
view.setTorchMode(torchMode);

View File

@ -69,6 +69,15 @@ RCT_EXPORT_VIEW_PROPERTY(keepAwake, BOOL);
@"still": @(RCTCameraCaptureModeStill),
@"video": @(RCTCameraCaptureModeVideo)
},
@"CaptureQuality": @{
@"low": AVCaptureSessionPresetLow,
@"AVCaptureSessionPresetLow": AVCaptureSessionPresetLow,
@"medium": AVCaptureSessionPresetMedium,
@"AVCaptureSessionPresetMedium": AVCaptureSessionPresetMedium,
@"high": AVCaptureSessionPresetHigh,
@"AVCaptureSessionPresetHigh": AVCaptureSessionPresetHigh,
@"AVCaptureSessionPresetPhoto": AVCaptureSessionPresetPhoto
},
@"CaptureTarget": @{
@"memory": @(RCTCameraCaptureTargetMemory),
@"disk": @(RCTCameraCaptureTargetDisk),
@ -136,7 +145,6 @@ RCT_EXPORT_VIEW_PROPERTY(onZoomChanged, BOOL)
if ((self = [super init])) {
self.session = [AVCaptureSession new];
self.session.sessionPreset = AVCaptureSessionPresetHigh;
self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
self.previewLayer.needsDisplayOnBoundsChange = YES;
@ -257,6 +265,8 @@ RCT_EXPORT_METHOD(capture:(NSDictionary *)options
NSInteger captureMode = [[options valueForKey:@"mode"] intValue];
NSInteger captureTarget = [[options valueForKey:@"target"] intValue];
[self setCaptureQuality:[options valueForKey:@"quality"]];
if (captureMode == RCTCameraCaptureModeStill) {
[self captureStill:captureTarget options:options resolve:resolve reject:reject];
}
@ -842,4 +852,15 @@ didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
}
}
- (void)setCaptureQuality:(NSString *)quality
{
if (quality) {
[self.session beginConfiguration];
if ([self.session canSetSessionPreset:quality]) {
self.session.sessionPreset = quality;
}
[self.session commitConfiguration];
}
}
@end