Merge pull request #211 from rpopovici/master
set capture quality on android and iOS
This commit is contained in:
commit
bdb48c3956
11
Camera.js
11
Camera.js
|
@ -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: '',
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue