How to handle camera flash android camera2 API? - android

I want to set flash off,on and auto as user selection. How should I do that?
In this code if I enable flash it is on but when I click image flash goes off. And when I change camera at that time also flash goes off.
If the user sets flash to enable then when the user clicks an image only at that time flash should go on and after that it should be off.
public class MainActivity extends AppCompatActivity {
protected CameraDevice cameraDevice;
protected CameraCaptureSession cameraCaptureSessions;
protected CaptureRequest.Builder captureRequestBuilder;
private boolean deviceHasFlash;
private boolean flashStatus=false;
private String cameraId=CAMERA_BACK;
private Size imageDimension;
private ImageReader imageReader;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
private static final int PERMISSION_CODE = 200;
public static final String CAMERA_FRONT = "1";
public static final String CAMERA_BACK = "0";
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
ImageView captureImage;
ImageView flash;
ImageView switchCamera;
private TextureView textureView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
captureImage = findViewById(R.id.btn_camera_shutter);
textureView = (TextureView) findViewById(R.id.textureView);
flash=findViewById(R.id.btn_flash);
switchCamera=findViewById(R.id.btn_camera_switch);
if (checkPermission()) {
setCameraView();
createFolderIfNotExists();
Log.e("DB", "Permission is Given");
} else {
Log.e("DB", "Ask For Permission");
requestPermission();
}
captureImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
takePicture();
}
});
switchCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
switchCameraFunction();
}
});
flash.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
deviceHasFlash = getApplication().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if(!deviceHasFlash){
Toast.makeText(MainActivity.this, "Sorry, you device does not have any camera", Toast.LENGTH_LONG).show();
}
else {
if(flashStatus){
flashOff();
flash.setImageResource(R.drawable.ic_flash_off);
flashStatus=false;
}
else {
flashOn();
flash.setImageResource(R.drawable.ic_flash_on);
flashStatus=true;
}
}
}
});
}
private void switchCameraFunction() {
if (cameraId.equals(CAMERA_FRONT)) {
cameraId = CAMERA_BACK;
closeCamera();
reopenCamera();
} else if (cameraId.equals(CAMERA_BACK)) {
cameraId = CAMERA_FRONT;
closeCamera();
reopenCamera();
}
}
private void reopenCamera() {
if (textureView.isAvailable()) {
Log.e("DB", "reopenCamera if");
openCamera();
} else {
Log.e("DB", "reopenCamera else");
textureView.setSurfaceTextureListener(textureListener);
}
}
private void flashOff() {
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void flashOn() {
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void setCameraView() {
assert textureView != null;
textureView.setSurfaceTextureListener(textureListener);
}
private void createFolderIfNotExists() {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "CrazyCam");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
if (success) {
Log.e("DB", "Folder Created");
} else {
Log.e("DB", "Something Wrong");
}
} else {
Log.e("DB", "Folder exists");
}
}
private boolean checkPermission() {
int readExternal = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
int writeExternal = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int camera = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);
return camera == PackageManager.PERMISSION_GRANTED && writeExternal == PackageManager.PERMISSION_GRANTED && readExternal == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{WRITE_EXTERNAL_STORAGE, CAMERA, READ_EXTERNAL_STORAGE}, PERMISSION_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_CODE:
if (grantResults.length > 0) {
boolean wrireExteernal = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean readExternal = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (wrireExteernal && cameraAccepted && readExternal) {
setCameraView();
createFolderIfNotExists();
Log.e("DB", "Permission is Given");
} else {
Toast.makeText(getApplicationContext(), "All Permission Requeid", Toast.LENGTH_LONG).show();
System.exit(0);
}
}
}
}
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Log.e("DB", "is camera open");
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
Log.e("DB","imageDimension===>"+imageDimension);
// Add permission for camera and let user grant the permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_CODE);
return;
}
manager.openCamera(cameraId, stateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e("DB", "openCamera X");
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
openCamera();
Log.e("DB","onSurfaceTextureAvailable");
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
//This is called when the camera is open
Log.e("DB", "onOpened");
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice = null;
}
};
/* #Override
protected void onDestroy() {
closeCamera();
Log.e("DB","On Destroy Call");
super.onDestroy();
}
*/
private void closeCamera() {
if (null != cameraDevice) {
cameraDevice.close();
cameraDevice = null;
}
if (null != imageReader) {
imageReader.close();
imageReader = null;
}
}
protected void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
protected void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
Log.e("DB", "onResume");
startBackgroundThread();
if (textureView.isAvailable()) {
Log.e("DB", "textureView if");
openCamera();
} else {
Log.e("DB", "textureView else");
textureView.setSurfaceTextureListener(textureListener);
}
}
#Override
protected void onPause() {
Log.e("DB", "onPause");
closeCamera();
stopBackgroundThread();
super.onPause();
}
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void updatePreview() {
if(null == cameraDevice) {
Log.e("DB", "updatePreview error, return");
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void takePicture() {
if(null == cameraDevice) {
Log.e("DB", "cameraDevice is null");
return;
}
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
Size[] jpegSizes = null;
if (characteristics != null) {
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
}
int width = 640;
int height = 480;
for(int i=0;i<jpegSizes.length;i++){
Log.e("DB==>","Size:"+jpegSizes[i]);
}
if (jpegSizes != null && 0 < jpegSizes.length) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
final File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "CrazyCam");
String fileName = String.format("CrazyCam_" + System.currentTimeMillis() + ".jpg");
final File outFile = new File(folder, fileName);
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (image != null) {
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(outFile);
outStream.write(bytes);
outStream.flush();
} finally {
if (null != outStream) {
outStream.close();
}
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(getApplicationContext(), "Image Save at " + folder, Toast.LENGTH_LONG).show();
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}

Related

How get barcode row value from camera preview in TextureView?

I'm noob in android.
Can anybody help to anderstanding google ml-kit barcodereader?
I create activity with TextureView.
Camera live-preview in TextureView.
In activity code i create scanBarcode(Bitmap bitmap) method.
But I can't get barcode value.(((
I use this tutorial to Create scanBarcode method.
https://firebase.google.com/docs/ml-kit/android/read-barcodes
What i do wrong?
public class BarcodeScannerActivityNew extends AppCompatActivity {
private TextureView textureView; //элемент где будет превью
private String cameraId; //id камеры, с которой будем забирать изображение
private Size imageDimension; // размер изображения с камеры
private static final int REQUEST_CAMERA_PERMISSION = 200; //200 - разрешение есть
protected CameraDevice cameraDevice; // камера для колбэка
protected CaptureRequest.Builder captureRequestBuilder; // создание запроса к camera2
protected CameraCaptureSession cameraCaptureSessions;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
private String bcTitle;
private TextView txt;
//private FirebaseVisionImage fbImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode_scanner_new);
textureView = (TextureView) findViewById(R.id.texture);
textureView.setSurfaceTextureListener(textureListener);
txt = (TextView) findViewById(R.id.editText);
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
openCamera(); //открываем камеру
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Изменяем размер превью по элементу TextureView
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// сюда бабахнуть сканнер??
}
};
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = manager.getCameraIdList()[0]; // первая камера
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
// Проверяем есть ли разрешения для камеры, если нет запрашиваем
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(BarcodeScannerActivityNew.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallback, null); //колбэк камеры
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
//Когда камера открыта
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(CameraDevice camera) {
cameraDevice.close();
}
#Override
public void onError(CameraDevice camera, int error) {
cameraDevice.close();
cameraDevice = null;
}
};
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
final Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
//Камера закрыта
if (null == cameraDevice) {
return;
}
// Когда сессия готова показываем.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(BarcodeScannerActivityNew.this, "Настройки изменились", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void updatePreview() {
if(null == cameraDevice) {
//вывод ошибки обновления превью
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
try {
Bitmap bitmapi = textureView.getBitmap();
if(bitmapi!=null){
scanBarcode(bitmapi);
}
if(bcTitle != null){
txt.setText(bcTitle);
}
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
// Закрыть приложение
Toast.makeText(BarcodeScannerActivityNew.this, "Без разрешения камеры невозможно использовать приложение", Toast.LENGTH_LONG).show();
finish();
}
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (textureView.isAvailable()) {
openCamera();
} else {
textureView.setSurfaceTextureListener(textureListener);
}
}
protected void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
protected void onPause() {
//closeCamera();
stopBackgroundThread();
super.onPause();
}
protected void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void scanBarcode(Bitmap bitmap){
FirebaseVisionBarcodeDetectorOptions options =
new FirebaseVisionBarcodeDetectorOptions.Builder()
.setBarcodeFormats(
FirebaseVisionBarcode.FORMAT_EAN_13)
.build();
//bcTitle="куку";
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance()
.getVisionBarcodeDetector(options);
//bcTitle="куку";
Task<List<FirebaseVisionBarcode>> result = detector.detectInImage(image)
.addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionBarcode>>() {
#Override
public void onSuccess(List<FirebaseVisionBarcode> barcodes) {
// Task completed successfully
// ...
//bcTitle="aaa";//сюда попадаем после разблокировки экрана, возможно перперисовать интерфейс, даже если ничего не поймал
for (FirebaseVisionBarcode barcode: barcodes) {
bcTitle="aaa";
Rect bounds = barcode.getBoundingBox();
Point[] corners = barcode.getCornerPoints();
String rawValue = barcode.getRawValue();
int valueType = barcode.getValueType();
bcTitle = barcode.getRawValue();
// See API reference for complete list of supported types
/*
switch (valueType) {
case FirebaseVisionBarcode.TYPE_WIFI:
String ssid = barcode.getWifi().getSsid();
String password = barcode.getWifi().getPassword();
int type = barcode.getWifi().getEncryptionType();
break;
case FirebaseVisionBarcode.TYPE_URL:
String title = barcode.getUrl().getTitle();
String url = barcode.getUrl().getUrl();
break;
}
*/
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Task failed with an exception
// ...
bcTitle="ffff";
}
});
}
}

Android textureView stretched

SurfaceTexture preview is stretched! I'm developing a camera2 app. Every device is working bad. The preview for video and photo is stretched.
public class CamActivity extends AppCompatActivity {
private static final int REQUEST_LOCATION = 1;
LocationManager locationManager;
Animation animFadeOut, textAnimFadeOut;
ImageView viewFadeOut;
TextView textFadeOut, Lado;
private TextureView textureView;
private FloatingActionButton btnCapture;
//Check state orientation of output image
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0,0);
}
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSessions;
private CaptureRequest.Builder captureRequestBuilder;
private Size imageDimension;
private ImageReader imageReader;
//Save to FILE
private File file;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private boolean mFlashSupported;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice=null;
}
};
#SuppressLint("WrongViewCast")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cam);
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
Lado = (TextView)findViewById(R.id.lado_armadilha);
Lado.setText(getIntent().getStringExtra("lado_armadilha"));
viewFadeOut = (ImageView)findViewById(R.id.viewFadeOut);
animFadeOut = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
viewFadeOut.startAnimation(animFadeOut);
textFadeOut =(TextView)findViewById(R.id.textFadeOut);
textAnimFadeOut = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_text);
textFadeOut.startAnimation(textAnimFadeOut);
textureView = (TextureView)findViewById(R.id.textureView);
//From Java 1.4 , you can use keyword 'assert' to check expression true or false
assert textureView != null;
textureView.setSurfaceTextureListener(textureListener);
btnCapture = (FloatingActionButton) findViewById(R.id.btnCapture);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
takePicture();
}
});
}
private void takePicture() {
if(cameraDevice == null)
return;
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if(characteristics != null)
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG);
Log.i("JPEG_SIZE", "" + jpegSizes[0].getWidth());
Log.i("JPEG_SIZE", "" + jpegSizes[0].getHeight());
//Capture image with custom size
int width = jpegSizes[0].getWidth();
int height =jpegSizes[0].getHeight();
if(jpegSizes == null && jpegSizes.length < 0)
{
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
final ImageReader reader = ImageReader.newInstance(width,height,ImageFormat.JPEG,1);
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
//Check orientation base on device
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
file = new File(getIntent().getStringExtra(MediaStore.EXTRA_OUTPUT));
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try {
image = reader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
Log.e("ioexception", e.getMessage());
}
finally {
if(image != null)
image.close();
}
Intent intent = new Intent();
intent.putExtra("Bitmap",file.getAbsolutePath());
setResult(1,intent);
finish();
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
} finally {
if(outputStream != null)
outputStream.close();
}
}
};
reader.setOnImageAvailableListener(readerListener,mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(CamActivity.this, "Saved "+file, Toast.LENGTH_SHORT).show();
}
};
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
try {
cameraCaptureSession.capture(captureBuilder.build(),captureListener,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
}
},mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
if (cameraDevice == null)
return;
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(CamActivity.this, "Changed", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE,CaptureRequest.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
//Check realtime permission if run higher API 23
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId,stateCallback,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CAMERA_PERMISSION)
{
if(grantResults[0] != PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "You can't use camera without permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if(textureView.isAvailable())
openCamera();
else
textureView.setSurfaceTextureListener(textureListener);
}
#Override
protected void onPause() {
stopBackgroundThread();
super.onPause();
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread= null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
}
A TextureView will by default just stretch whatever images you give it into its view dimensions. So if you give it a 1920x1080 buffer (16:9 aspect ratio) but its dimensions are 1600x1200 (4:3), you'll get a vertically squished image shown.
Take a look at the AutoFitTextureView in the Camera2Basic sample from Google.
It tries to ensure that its aspect ratio matches that of the camera, but it does require you to set its layout parameters correctly (and it has to be in a layout container that allows its children some flexibility in sizing).

why video is getting stretched in camera2 API?

I am building a video camera app which is always be in landscape mode and always record from front camera.
But when I am recording the video it looks like stretched.How to solve it?
Where I am making mistake??
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;
public static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT = 1;
private TextureView mTextureView;
//public ImageView mImageView;
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
//Toast.makeText(getApplicationContext(),"TextureView is Available",Toast.LENGTH_SHORT).show();
setupCamera(width, height);
connectCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
private CameraDevice mCameraDevice;
private CameraDevice.StateCallback mCameraDeviceStateCallback;
{
mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
mMediaRecorder = new MediaRecorder();
if (mIsRecording) {
try {
createVideoFileName();
} catch (IOException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
startRecord();
mMediaRecorder.start();
runOnUiThread(new Runnable() {
#Override
public void run() {
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.setVisibility(View.VISIBLE);
mChronometer.start();
}
});
} else {
startPreview();
}
//Toast.makeText(getApplicationContext(),"Camera connected",Toast.LENGTH_SHORT).show();
}
#Override
public void onDisconnected(CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
#Override
public void onError(CameraDevice camera, int i) {
}
};
}
private HandlerThread mBackgroundHandlerThread;
private Handler mBackgroundHandler;
private String mCameraId;
private Size mPreviewSize;
private Size mVideoSize;
private MediaRecorder mMediaRecorder;
private Chronometer mChronometer;
private ImageView thumb;
//private String V1, V2, V3, V4, V5;
// private Map<String, String> mapA = new HashMap<>();
// private ImageView[] IMGS = {mImageView1, mImageView2, mImageView3, mImageView4, mImageView5};
private int mTotalRotation;
private CaptureRequest.Builder mCaptureRequestBuilder;
public static int count;
public static int max = 5;
private ImageButton mRecordImageButton;
private boolean mIsRecording = false;
public static File mVideoFolder;
private static File mRawVideoFolder;
public static String mVideoFileName;
//Test
private List<Bitmap> bitMapsAvailable = new ArrayList<>();
private List<String> bitMapsFilePath = new ArrayList<>();
private int bitMapIndex;
CameraCaptureSession storedSession;
private ArrayAdapter bitMapAdapter;
private ArrayAdapter bitMapFileAdapter;
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
public int index;
static {
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private static class CompareSizeByArea implements Comparator<Size> {
#Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) lhs.getWidth() * lhs.getHeight() / (long) rhs.getWidth() * rhs.getHeight());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
createVideoFolder();
mMediaRecorder = new MediaRecorder();
mChronometer = (Chronometer) findViewById(R.id.chronometer);
mTextureView = (TextureView) findViewById(R.id.textureView);
mRecordImageButton = (ImageButton) findViewById(R.id.videoButton);
mRecordImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mIsRecording) {
mChronometer.stop();
mChronometer.setVisibility(View.INVISIBLE);
mIsRecording = false;
mRecordImageButton.setImageResource(R.mipmap.start_recording);
//Toast.makeText(getApplicationContext(),"Started",Toast.LENGTH_SHORT).show();
if(storedSession != null){
try {
storedSession.stopRepeating();
storedSession.abortCaptures();
}catch (CameraAccessException e){
throw new RuntimeException(e.getMessage());
}
}
mMediaRecorder.stop();
mMediaRecorder.reset();
startPreview();
//Create bitmap with current video file path
Bitmap bitMap = ThumbnailUtils.createVideoThumbnail(mVideoFileName, MediaStore.Video.Thumbnails.MICRO_KIND);
//Add bitmap to array list
bitMapsAvailable.add(bitMap);
bitMapsFilePath.add(mVideoFileName);
// Shows thumbnails
showThumbnails();
} else {
checkWriteStoragePermission();
}
}
});
}
private void showThumbnails() {
LinearLayout layout = (LinearLayout) findViewById(R.id.thumbnails);
bitMapAdapter = new ArrayAdapter(this, R.layout.activity_main, bitMapsAvailable);
bitMapFileAdapter = new ArrayAdapter(this, R.layout.activity_main, bitMapsFilePath);
bitMapIndex = 0;
if (layout.getChildCount() > 0) {
layout.removeAllViews();
}
for (Bitmap eachBitMap : bitMapsAvailable) {
bitMapIndex++;
ImageView thumb = new ImageView(this);
thumb.setId(new Integer(bitMapIndex+ 17));
thumb.setLayoutParams(new android.view.ViewGroup.LayoutParams(100, 80));
thumb.setImageBitmap(eachBitMap);
// Adds the view to the layout
thumb.setOnClickListener(previewThumb(thumb));
layout.addView(thumb);
}
}
View.OnClickListener previewThumb(final ImageView imageview) {
return new View.OnClickListener() {
public void onClick(View arg0) {
index = imageview.getId()-18;
imageview.setBackgroundColor(0xff999999);
// Start NewActivity.class
Intent myIntent = new Intent(MainActivity.this,
VideoViewActivity.class);
Bundle bundle = new Bundle();
bundle.putStringArrayList("bitMapsAvailable", new ArrayList(bitMapsAvailable));
bundle.putStringArrayList("bitMapsFilePath", new ArrayList(bitMapsFilePath));
//Add your data to bundle
bundle.putInt("urlIndex", index);
myIntent.putExtras(bundle);
bitMapAdapter.notifyDataSetChanged();
bitMapFileAdapter.notifyDataSetChanged();
// startActivity(myIntent);
startActivityForResult(myIntent, 111);
}
};
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 111) {
int indexToBeDeleted = data.getIntExtra("indexToBeDeleted",index);
//bitMapsFilePath.remove(indexToBeDeleted);
bitMapsAvailable.remove(indexToBeDeleted);
}
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (mTextureView.isAvailable()) {
setupCamera(mTextureView.getWidth(), mTextureView.getHeight());
connectCamera();
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permission, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permission, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION_RESULT) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Application will not run without camera service", Toast.LENGTH_SHORT).show();
}
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Application will not have audio on record ", Toast.LENGTH_SHORT).show();
}
}
if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mIsRecording = true;
mRecordImageButton.setImageResource(R.mipmap.ic_launcher);
try {
createVideoFileName();
} catch (IOException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
Toast.makeText(this, "Permission Successfully Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "App needs to save video to run", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onPause() {
closeCamera();
stopBackgroundThread();
super.onPause();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View decorView = getWindow().getDecorView();
if (hasFocus) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
private void setupCamera(int width, int height) {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
//int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation();
mTotalRotation = sensorToDeviceRotation(cameraCharacteristics);
boolean swapRotation = mTotalRotation == 90 || mTotalRotation == 270;
int rotateWidth = width;
int rotateHeight = height;
if (swapRotation) {
rotateWidth = height;
rotateHeight = width;
}
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotateWidth, rotateHeight);
mVideoSize = chooseOptimalSize(map.getOutputSizes(MediaRecorder.class), rotateWidth, rotateHeight);
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
private void connectCamera() {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
Toast.makeText(this, "Video app required access to camera", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, REQUEST_CAMERA_PERMISSION_RESULT);
}
} else {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
}
} catch (CameraAccessException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
private void startRecord() {
if (this.bitMapsAvailable.size() < max) {
try {
setupMediaRecorder();
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
Surface recordSurface = mMediaRecorder.getSurface();
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mCaptureRequestBuilder.addTarget(previewSurface);
mCaptureRequestBuilder.addTarget(recordSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
try {
session.setRepeatingRequest(mCaptureRequestBuilder.build(), null, null);
storedSession = session;
} catch (CameraAccessException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, null);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
} else {
}
}
private void startPreview() {
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
try {
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mCaptureRequestBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
try {
session.stopRepeating();
session.abortCaptures();
session.setRepeatingRequest(mCaptureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
Toast.makeText(getApplicationContext(), "Unable to setup Camera Preview", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
private void closeCamera() {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
private void startBackgroundThread() {
mBackgroundHandlerThread = new HandlerThread("AuthorTV");
mBackgroundHandlerThread.start();
mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundHandlerThread.quitSafely();
try {
mBackgroundHandlerThread.join();
mBackgroundHandlerThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
private static int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics) {
int sensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
// deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return (sensorOrientation + 180 + 360) % 360;
}
private static Size chooseOptimalSize(Size[] choices, int width, int height) {
List<Size> bigEnough = new ArrayList<Size>();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * height / width && option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizeByArea());
} else {
return choices[0];
}
}
private void setupMediaRecorder() throws IOException {
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mVideoFileName);
mMediaRecorder.setVideoEncodingBitRate(1000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setOrientationHint(mTotalRotation);
mMediaRecorder.prepare();
}
chooseOptimalSize needs to be adjusted and different for mPreviewSize and mVideoSize. Check this link Camera2VideoFragment.java

Taking images camera2api

I need help with this code. It gives me this error
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CaptureRequest$Builder.set(android.hardware.camera2.CaptureRequest$Key, java.lang.Object)' on a null object reference
My code is
private int mState = STATE_PREVIEW;
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;
private static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT = 1;
private static final int STATE_PREVIEW = 0;
private static final int STATE_WAIT_LOCK = 1;
private int mCaptureState = STATE_PREVIEW;
private TextureView mTextureView;
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width, height);
connectCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private CameraDevice mCameraDevice;
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
startPreview();
}
#Override
public void onDisconnected(CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
#Override
public void onError(CameraDevice camera, int error) {
camera.close();
mCameraDevice = null;
}
};
private HandlerThread mBackgroundHandlerThread;
private Handler mBackgroundHandler;
private String mCameraId;
private Size mPreviewSize;
private Size mImageSize;
private ImageReader mImageReader;
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new
ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
mBackgroundHandler.post(new ImageSaver(reader.acquireLatestImage()));
}
};
private class ImageSaver implements Runnable {
private final Image mImage;
public ImageSaver(Image image) {
mImage = image;
}
#Override
public void run() {
ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(mImageFileName);
fileOutputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
if(fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private MediaRecorder mMediaRecorder;
private int mTotalRotation;
private CameraCaptureSession mPreviewCaptureSession;
private CameraCaptureSession.CaptureCallback mPreviewCaptureCallback = new
CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult captureResult) {
switch (mCaptureState) {
case STATE_PREVIEW:
// Do nothing
break;
case STATE_WAIT_LOCK:
mCaptureState = STATE_PREVIEW;
Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
if(afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Toast.makeText(getApplicationContext(), "AF Locked!", Toast.LENGTH_SHORT).show();
startStillCaptureRequest();
}
break;
}
}
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
process(result);
}
};
private CaptureRequest mPreviewCaptureRequest;
private CaptureRequest.Builder mPreviewCaptureRequestBuilder;
private CameraCaptureSession mCameraCaptureSession;
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback
= new CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult result) {
switch(mState) {
case STATE_PREVIEW:
// Do nothing
break;
case STATE_WAIT_LOCK:
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if(afState == CaptureRequest.CONTROL_AF_STATE_FOCUSED_LOCKED) {
/*
unLockFocus();
Toast.makeText(getApplicationContext(), "Focus Lock Successful", Toast.LENGTH_SHORT).show();
*/
captureStillImage();
}
break;
}
}
#Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
}
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
process(result);
}
#Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
Toast.makeText(getApplicationContext(), "Focus Lock Unsuccessful", Toast.LENGTH_SHORT).show();
}
};
private CaptureRequest.Builder mCaptureRequestBuilder;
private File mImageFolder;
private String mImageFileName;
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private static class CompareSizeByArea implements Comparator<Size> {
#Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) lhs.getWidth() * lhs.getHeight() /
(long) rhs.getWidth() * rhs.getHeight());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
createImageFolder();
mTextureView = (TextureView) findViewById(R.id.textureView);
final Button button = (Button) findViewById(R.id.camera_button);
if (button != null) {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePicture();
}
});
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (mTextureView.isAvailable()) {
setupCamera(mTextureView.getWidth(), mTextureView.getHeight());
connectCamera();
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == REQUEST_CAMERA_PERMISSION_RESULT) {
if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(),
"Application will not run without camera services", Toast.LENGTH_SHORT).show();
}
if(grantResults[1] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(),
"Application will not have audio on record", Toast.LENGTH_SHORT).show();
}
}
if(requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,
"Permission successfully granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,
"App needs to save image to run", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onPause() {
closeCamera();
stopBackgroundThread();
super.onPause();
}
#Override
public void onWindowFocusChanged(boolean hasFocas) {
super.onWindowFocusChanged(hasFocas);
View decorView = getWindow().getDecorView();
if(hasFocas) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
private void setupCamera(int width, int height) {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for(String cameraId : cameraManager.getCameraIdList()){
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) ==
CameraCharacteristics.LENS_FACING_FRONT){
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation();
mTotalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
boolean swapRotation = mTotalRotation == 90 || mTotalRotation == 270;
int rotatedWidth = width;
int rotatedHeight = height;
if(swapRotation) {
rotatedWidth = height;
rotatedHeight = width;
}
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
mImageSize = chooseOptimalSize(map.getOutputSizes(ImageFormat.JPEG), rotatedWidth, rotatedHeight);
mImageReader = ImageReader.newInstance(mImageSize.getWidth(), mImageSize.getHeight(), ImageFormat.JPEG, 1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void connectCamera() {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
} else {
if(shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA)) {
Toast.makeText(this,
"Video app required access to camera", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[] {android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO
}, REQUEST_CAMERA_PERMISSION_RESULT);
}
} else {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startPreview() {
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
try {
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mCaptureRequestBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
mPreviewCaptureSession = session;
try {
mPreviewCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(),
null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(getApplicationContext(),
"Unable to setup camera preview", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startStillCaptureRequest() {
mCaptureRequestBuilder.addTarget(mImageReader.getSurface());
mCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mTotalRotation);
CameraCaptureSession.CaptureCallback stillCaptureCallback = new
CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
try {
createImageFileName();
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
private void closeCamera() {
if(mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
if(mMediaRecorder != null) {
mMediaRecorder.release();
mMediaRecorder = null;
}
}
private void startBackgroundThread() {
mBackgroundHandlerThread = new HandlerThread("CameraImage");
mBackgroundHandlerThread.start();
mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundHandlerThread.quitSafely();
try {
mBackgroundHandlerThread.join();
mBackgroundHandlerThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation) {
int sensorOrienatation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return (sensorOrienatation + deviceOrientation + 360) % 360;
}
private static Size chooseOptimalSize(Size[] choices, int width, int height) {
List<Size> bigEnough = new ArrayList<Size>();
for(Size option : choices) {
if(option.getHeight() == option.getWidth() * height / width &&
option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
if(bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizeByArea());
} else {
return choices[0];
}
}
private void createImageFolder() {
File imageFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
mImageFolder = new File(imageFile, "camera2VideoImage");
if(!mImageFolder.exists()) {
mImageFolder.mkdirs();
}
}
private File createImageFileName() throws IOException {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "IMAGE_" + timestamp + "_";
File imageFile = File.createTempFile(prepend, ".jpg", mImageFolder);
mImageFileName = imageFile.getAbsolutePath();
return imageFile;
}
private void captureStillImage() {
try {
CaptureRequest.Builder captureStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureStillBuilder.addTarget(mImageReader.getSurface());
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureStillBuilder.set(CaptureRequest.JPEG_ORIENTATION,
ORIENTATIONS.get(rotation));
CameraCaptureSession.CaptureCallback captureCallback =
new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(getApplicationContext(),
"Image Captured!", Toast.LENGTH_SHORT).show();
unLockFocus();
}
};
mCameraCaptureSession.capture(
captureStillBuilder.build(), captureCallback, null
);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void takePicture() {
lockFocus();
}
private void lockFocus() {
try {
mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_START);
mState = STATE_WAIT_LOCK;
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),
mSessionCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void unLockFocus() {
try {
mState = STATE_PREVIEW;
mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),
mSessionCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
stack trace:
05-29 13:23:15.601 511-511/com.example.pc.snadfinal E/AndroidRuntime: FATAL >EXCEPTION: main
Process: >com.example.pc.snadfinal, PID: 511
Theme: >themes:{}
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CaptureRequest$Builder.set(android.hardware.camera2.CaptureRequest$Key, java.lang.Object)' on a null object reference
at com.example.pc.snadfinal.CameraActivity.lockFocus(CameraActivity.java:548)
at com.example.pc.snadfinal.CameraActivity.takePicture(CameraActivity.java:541)
at com.example.pc.snadfinal.CameraActivity.access$1100(CameraActivity.java:48)
at com.example.pc.snadfinal.CameraActivity$6.onClick(CameraActivity.java:259)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21158)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I think that error is caused by something in method lockFocus() or takePicture() and I don't know by what.
I added this to the lockFocus() and unlockFocus()
mPreviewCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
and now it gives me this stacktrace :
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.hardware.camera2.CameraCaptureSession.capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession$CaptureCallback, android.os.Handler)' on a null object reference
at com.example.pc.snadfinal.CameraActivity.lockFocus(CameraActivity.java:548)
at com.example.pc.snadfinal.CameraActivity.takePicture(CameraActivity.java:538)
at com.example.pc.snadfinal.CameraActivity.access$1000(CameraActivity.java:48)
at com.example.pc.snadfinal.CameraActivity$6.onClick(CameraActivity.java:256)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21158)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I just add a catch(Exception e) to make sure the App will not crash。。。
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
setAutoFlash(mPreviewRequestBuilder);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
I just solved the same problem. It is because the camera is not ready to capture image. Just maintain a short interval( 1 sec is enough ) between start() and takePicture().
It's working for me, Hope it will help... :-)
After some test and with #Neo answer i resolved to set the click listener of the takePictureButton after the camera preview is up

How to set a ThumbnailView of picture gallery in Android

I have developed a camera app using the latest camera2 API ,i want to set a thumbnail view of gallery on the screen ,like the camera in jellybean and ICS.Can anybody help me ?? how to do that .??
XML
<TextureView
android:id="#+id/texture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/btn_takepicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="picture" />
</RelativeLayout>
java
public class SecondActivity extends Activity {
private final static String TAG = "Camera2testJ";
private Size mPreviewSize;
private TextureView mTextureView;
private CameraDevice mCameraDevice;
private CaptureRequest.Builder mPreviewBuilder;
private CameraCaptureSession mPreviewSession;
private Button mBtnShot;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_second);
mTextureView = (TextureView)findViewById(R.id.texture);
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
mBtnShot = (Button)findViewById(R.id.btn_takepicture);
mBtnShot.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e(TAG, "mBtnShot clicked");
takePicture();
}
});
}
protected void takePicture() {
Log.e(TAG, "takePicture");
if(null == mCameraDevice) {
Log.e(TAG, "mCameraDevice is null, return");
return;
}
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraDevice.getId());
Size[] jpegSizes = null;
if (characteristics != null) {
jpegSizes = characteristics
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG);
}
int width = 640;
int height = 480;
if (jpegSizes != null && 0 < jpegSizes.length) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(mTextureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
final File file = new File(Environment.getExternalStorageDirectory()+"/DCIM", "pic.jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (image != null) {
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream output = null;
try {
output = new FileOutputStream(file);
output.write(bytes);
} finally {
if (null != output) {
output.close();
}
}
}
};
HandlerThread thread = new HandlerThread("CameraPicture");
thread.start();
final Handler backgroudHandler = new Handler(thread.getLooper());
reader.setOnImageAvailableListener(readerListener, backgroudHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(SecondActivity.this, "Saved:"+file, Toast.LENGTH_SHORT).show();
startPreview();
}
};
mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, backgroudHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, backgroudHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume");
}
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Log.e(TAG, "openCamera E");
try {
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
manager.openCamera(cameraId, mStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "openCamera X");
}
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener(){
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.e(TAG, "onSurfaceTextureAvailable, width="+width+",height="+height);
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface,
int width, int height) {
Log.e(TAG, "onSurfaceTextureSizeChanged");
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//Log.e(TAG, "onSurfaceTextureUpdated");
}
};
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
Log.e(TAG, "onOpened");
mCameraDevice = camera;
startPreview();
}
#Override
public void onDisconnected(CameraDevice camera) {
Log.e(TAG, "onDisconnected");
}
#Override
public void onError(CameraDevice camera, int error) {
Log.e(TAG, "onError");
}
};
#Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
protected void startPreview() {
if(null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
Log.e(TAG, "startPreview fail, return");
return;
}
SurfaceTexture texture = mTextureView.getSurfaceTexture();
if(null == texture) {
Log.e(TAG,"texture is null, return");
return;
}
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
try {
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mPreviewBuilder.addTarget(surface);
try {
mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
mPreviewSession = session;
updatePreview();
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(SecondActivity.this, "onConfigureFailed", Toast.LENGTH_LONG).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void updatePreview() {
if(null == mCameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
HandlerThread thread = new HandlerThread("CameraPreview");
thread.start();
Handler backgroundHandler = new Handler(thread.getLooper());
try {
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}

Categories

Resources