I'm having some problems with CameraSource when I want to take a picture using the camera.
All i want is take a picture with a button i made on the xml file and use 'CameraSource' to take the photo because i'm using 'TextRecognizer' too.
The Camera is working fine but the problem occurs when i press the button to take a picture.
Manifest File:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
My Variables:
SurfaceView cameraView;
TextView textView;
CameraSource camera_source;
final int RequestCameraPermissionID = 1001;
Class:
// Starting the CameraSource. This will be in the 'OnCreate' function. This function works.
private void OpenCameraSource(){
final TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (!textRecognizer.isOperational()) {
Log.w("Steal_Activity", "Detector activity are not yet available");
Toast.makeText(getApplicationContext(),"Detector activity are not yet available",Toast.LENGTH_SHORT).show();
} else {
camera_source = new CameraSource.Builder(getApplicationContext(),textRecognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setRequestedFps(2.0f)
.setAutoFocusEnabled(true)
.build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Steal.this,
new String[]{android.Manifest.permission.CAMERA},
RequestCameraPermissionID);
return;
}
camera_source.start(cameraView.getHolder());
}catch (IOException ex){
ex.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
camera_source.stop();
}
});
textRecognizer.setProcessor(new Detector.Processor<TextBlock>() {
// Some Stuff here
}
});
}
}
// This function will be launched when the button is pressed
public void OnClick_TakeShot(View view){
try{//I GET ERROR HERE
camera_source.takePicture(null,pictureCallback);
}catch (Exception ex){
Toast.makeText(getApplicationContext(),"Error:"+ex.toString(),Toast.LENGTH_LONG).show();
}
}
// Callback for 'takePicture'
CameraSource.PictureCallback pictureCallback = new CameraSource.PictureCallback() {
#Override
public void onPictureTaken(byte[] bytes) {
File file_image = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+"/pics");
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes , 0, bytes .length);
if(bitmap!=null){
if(!file_image.isDirectory()){
file_image.mkdir();
}
file_image=new File(file_image,"mylastpic.jpg");
try{
FileOutputStream fileOutputStream=new FileOutputStream(file_image);
bitmap.compress(Bitmap.CompressFormat.JPEG,100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
}
catch(Exception exception) {
Toast.makeText(getApplicationContext(),"Error saving: "+ exception.toString(),Toast.LENGTH_LONG).show();
}
}
}
};
NOT WORKING WHEN I PRESS THE BUTTON TO TAKE PICTURE
Try using this way (i'm using OCR from Google Vision and for taking picture with CameraSource) Pd: the flash button i havent fix it yet...
YOU HAVE TO USE : compile 'com.google.android.gms:play-services-vision:9.2.1' in your dependecies for the OCR compatibility
public class CustomCamaraActivity extends BaseActivity implements Callback,
OnClickListener {
private Context context;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private Button flipCamera;
private Button flashCameraButton;
private Button captureImage;
private Button BtnCapturarFoto;
private int cameraId;
private boolean flashmode = false;
private int rotation;
private ActionBar actionBar;
private CameraSource cameraSource;
private StringBuilder builder;
private TextView txTextoCapturado;
private static CustomCamaraActivity instance;
private Activity activity;
private String nombreProyecto;
public static final int REQUEST_IMAGE_CAPTURE = 0020;
private File file;
private String ubicacion;
private static final String TAG = "FOTOGRAFIA";
private int Height = 620, Width = 480;
private TextRecognizer recognizer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_camara_layout);
context = this;
// camera surface view created
cameraId = CameraInfo.CAMERA_FACING_BACK;
flipCamera = (Button) findViewById(R.id.flipCamera);
flashCameraButton = (Button) findViewById(R.id.flash);
captureImage = (Button) findViewById(R.id.captureImage);
BtnCapturarFoto = (Button) findViewById(R.id.btnCapturarFoto);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
txTextoCapturado = (TextView) findViewById(R.id.tvTextoCapturado);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
flipCamera.setOnClickListener(this);
captureImage.setOnClickListener(this);
flashCameraButton.setOnClickListener(this);
BtnCapturarFoto.setOnClickListener(this);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
/*if (Camera.getNumberOfCameras() > 1) {
flipCamera.setVisibility(View.VISIBLE);
}*/
if (!getBaseContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)) {
flashCameraButton.setVisibility(View.GONE);
flipCamera.setVisibility(View.GONE);
}
recognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (recognizer.isOperational()) {
cameraSource = new CameraSource.Builder(getApplicationContext(), recognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setRequestedFps(15.0f)
.setAutoFocusEnabled(true)
.build();
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CustomCamaraActivity.this, new String[]{Manifest.permission.CAMERA}, 100);
return;
}
try {
releaseCamera();
cameraSource.start(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(cameraSource != null){
cameraSource.stop();
}
}
});
recognizer.setProcessor(new Detector.Processor<TextBlock>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
final SparseArray<TextBlock> items = detections.getDetectedItems();
if (items.size() != 0) {
builder = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
TextBlock it = items.valueAt(i);
builder.append(it.getValue());
}
final String read = builder.toString().trim();
//String read = builder.toString().trim().replace(" ", "").replace("\n", "");
try{
runOnUiThread(new Runnable() {
#Override
public void run() {
txTextoCapturado.setText(read);
}
});
}catch (Exception ex){
Log.e("error","Error al actualizar texto OCR");
}
//It continues doing other things here
}
}
});
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 100:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
cameraSource.start(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
public String getUbicacion() {
return ubicacion;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
if (camera != null) {
camera.setPreviewCallback(null);
camera.setErrorCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
if(camera != null){
camera.setPreviewCallback(null);
camera.setErrorCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (!openCamera(CameraInfo.CAMERA_FACING_BACK)) {
alertCameraDialog();
}
}
private boolean openCamera(int id) {
boolean result = false;
cameraId = id;
//releaseCamera();
try {
camera = Camera.open(cameraId);
} catch (Exception e) {
e.printStackTrace();
}
if (camera != null) {
try {
setUpCamera(camera);
camera.setErrorCallback(new ErrorCallback() {
#Override
public void onError(int error, Camera camera) {
}
});
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
result = true;
} catch (IOException e) {
e.printStackTrace();
result = false;
releaseCamera();
}
}
return result;
}
private void setUpCamera(Camera c) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
rotation = getWindowManager().getDefaultDisplay().getRotation();
int degree = 0;
switch (rotation) {
case Surface.ROTATION_0:
degree = 0;
break;
case Surface.ROTATION_90:
degree = 90;
break;
case Surface.ROTATION_180:
degree = 180;
break;
case Surface.ROTATION_270:
degree = 270;
break;
default:
break;
}
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// frontFacing
rotation = (info.orientation + degree) % 330;
rotation = (360 - rotation) % 360;
} else {
// Back-facing
rotation = (info.orientation - degree + 360) % 360;
}
c.setDisplayOrientation(rotation);
Parameters params = c.getParameters();
showFlashButton(params);
List<String> focusModes = params.getSupportedFlashModes();
if (focusModes != null) {
if (focusModes
.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
params.setFlashMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
}
params.setRotation(rotation);
}
private void showFlashButton(Parameters params) {
boolean showFlash = (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH) && params.getFlashMode() != null)
&& params.getSupportedFlashModes() != null
&& params.getSupportedFocusModes().size() > 1;
flashCameraButton.setVisibility(showFlash ? View.VISIBLE
: View.INVISIBLE);
}
private void releaseCamera() {
try {
if (camera != null) {
camera.setPreviewCallback(null);
camera.setErrorCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
} catch (Exception e) {
e.printStackTrace();
Log.e("error", e.toString());
camera = null;
}
}
private void releaseCameraSource() {
try {
if (cameraSource != null) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
}
} catch (Exception e) {
e.printStackTrace();
Log.e("error", e.toString());
cameraSource = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.flash:
flashOnButton();
break;
case R.id.flipCamera:
flipCamera();
break;
case R.id.captureImage:
takeImage();
break;
case R.id.btnCapturarFoto:
takeImage();
break;
default:
break;
}
}
private void takeImage() {
try{
//openCamera(CameraInfo.CAMERA_FACING_BACK);
//releaseCameraSource();
//releaseCamera();
//openCamera(CameraInfo.CAMERA_FACING_BACK);
//setUpCamera(camera);
//Thread.sleep(1000);
cameraSource.takePicture(null, new CameraSource.PictureCallback() {
private File imageFile;
#Override
public void onPictureTaken(byte[] bytes) {
try {
// convert byte array into bitmap
Bitmap loadedImage = null;
Bitmap rotatedBitmap = null;
loadedImage = BitmapFactory.decodeByteArray(bytes, 0,
bytes.length);
// rotate Image
Matrix rotateMatrix = new Matrix();
rotateMatrix.postRotate(rotation);
rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
loadedImage.getWidth(), loadedImage.getHeight(),
rotateMatrix, false);
String state = Environment.getExternalStorageState();
File folder = null;
if (state.contains(Environment.MEDIA_MOUNTED)) {
folder = new File(Environment
.getExternalStorageDirectory() + "/Demo");
} else {
folder = new File(Environment
.getExternalStorageDirectory() + "/Demo");
}
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
java.util.Date date = new java.util.Date();
imageFile = new File(folder.getAbsolutePath()
+ File.separator
//+ new Timestamp(date.getTime()).toString()
+ "Image.jpg");
imageFile.createNewFile();
} else {
Toast.makeText(getBaseContext(), "Image Not saved",
Toast.LENGTH_SHORT).show();
return;
}
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
// save image into gallery
rotatedBitmap = resize(rotatedBitmap, 800, 600);
rotatedBitmap.compress(CompressFormat.JPEG, 100, ostream);
FileOutputStream fout = new FileOutputStream(imageFile);
fout.write(ostream.toByteArray());
fout.close();
ContentValues values = new ContentValues();
values.put(Images.Media.DATE_TAKEN,
System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA,
imageFile.getAbsolutePath());
CustomCamaraActivity.this.getContentResolver().insert(
Images.Media.EXTERNAL_CONTENT_URI, values);
setResult(Activity.RESULT_OK); //add this
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}catch (Exception ex){
txTextoCapturado.setText("Error al capturar fotografia!");
}
}
private void flipCamera() {
int id = (cameraId == CameraInfo.CAMERA_FACING_BACK ? CameraInfo.CAMERA_FACING_FRONT
: CameraInfo.CAMERA_FACING_BACK);
if (!openCamera(id)) {
alertCameraDialog();
}
}
private void alertCameraDialog() {
AlertDialog.Builder dialog = createAlert(CustomCamaraActivity.this,
"Camera info", "error to open camera");
dialog.setNegativeButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
private Builder createAlert(Context context, String title, String message) {
AlertDialog.Builder dialog = new AlertDialog.Builder(
new ContextThemeWrapper(context,
android.R.style.Theme_Holo_Light_Dialog));
dialog.setIcon(R.drawable.ic_launcher);
if (title != null)
dialog.setTitle(title);
else
dialog.setTitle("Information");
dialog.setMessage(message);
dialog.setCancelable(false);
return dialog;
}
private void flashOnButton() {
if (camera != null) {
try {
Parameters param = camera.getParameters();
if (flashmode) {
param.setFlashMode(Parameters.FLASH_MODE_OFF);
flashCameraButton.setBackground(getResources().getDrawable(R.drawable.ic_flash_off));
} else {
param.setFlashMode(Parameters.FLASH_MODE_TORCH);
flashCameraButton.setBackground(getResources().getDrawable(R.drawable.ic_flash_on));
}
//param.setFlashMode(!flashmode ? Parameters.FLASH_MODE_TORCH : Parameters.FLASH_MODE_OFF);
camera.setParameters(param);
flashmode = !flashmode;
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}
/**
* Metodo para cambiar el tamaƱo de la fotografia una resolucion predeterminada.
*
* #param image
* #param maxWidth
* #param maxHeight
* #return
*/
private Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
if (maxHeight > 0 && maxWidth > 0) {
int width = image.getWidth();
int height = image.getHeight();
float ratioBitmap = (float) width / (float) height;
float ratioMax = (float) maxWidth / (float) maxHeight;
int finalWidth = maxWidth;
int finalHeight = maxHeight;
if (ratioMax > 1) {
finalWidth = (int) ((float) maxHeight * ratioBitmap);
} else {
finalHeight = (int) ((float) maxWidth / ratioBitmap);
}
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
return image;
} else {
return image;
}
}
}
and here is the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<TextView
android:id="#+id/tvTextoCapturado"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
android:textColor="#color/white"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="10dp"
android:elevation="0dp"
android:orientation="horizontal"
android:weightSum="30">
<Button
android:id="#+id/flash"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_alignBaseline="#+id/captureImage"
android:layout_alignBottom="#+id/captureImage"
android:layout_marginLeft="27dp"
android:layout_marginRight="27dp"
android:layout_toLeftOf="#+id/captureImage"
android:layout_toStartOf="#+id/captureImage"
android:layout_weight="4"
android:background="#drawable/ic_flash_off"
android:gravity="center" />
<Button
android:id="#+id/captureImage"
android:layout_width="35dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="27dp"
android:layout_marginRight="27dp"
android:layout_weight="10"
android:background="#android:drawable/ic_menu_camera"
android:visibility="gone" />
<Button
android:id="#+id/btnCapturarFoto"
style="#style/blue_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="27dp"
android:layout_marginRight="27dp"
android:layout_weight="20"
android:elevation="0dp"
android:text="Tomar fotografia" />
<Button
android:id="#+id/flipCamera"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="27dp"
android:layout_marginRight="27dp"
android:layout_toRightOf="#id/captureImage"
android:layout_weight="4"
android:background="#drawable/ic_rotate"
android:visibility="invisible" />
</LinearLayout>
You can achieve it by CameraSource class like this:
mCameraSource = builder
.setFlashMode(if (useFlash) Camera.Parameters.FLASH_MODE_TORCH else null)
.build()
Add below code to the button click listener:
mCameraSource.takePicture(null, CameraSource.PictureCallback { data ->
// here data is a byteArray, you can play with it :)
}
You have to add the XML object "SurfaceView" to your activity, not declare it as a variable :
In your main_activity.xml
<SurfaceView
android:id="#+id/cameraView"
android:layout_width="match_parent"
android:layout_height="300dp" />
In your activity.kt
val cameraView: SurfaceView = findViewById(R.id.cameraView)
Related
This is my first attempt at accessing and clicking images using the Camera2Api.
I'm using the Nexus 5 running on API 23.
Though I can get the camera preview, but I cannot understand why does the frame gets locked after the capture request and also the images generated are blurry/totaly unclear.
I've been stuck with this issue for a while now. Any advise would be appreciated
Attached is my MainActivity Code:-
public class MainActivity extends AppCompatActivity implements
View.OnClickListener{
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);
}
private static final String TAG = "MainActivity";
private static final int STATE_PREVIEW=0;
private static final int STATE_WAIT_AF_LOCK=1;
private static final int STATE_PICTURE_CAPTURED=2;
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;
private static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT = 1;
private static final int REQUEST_READ_EXTERNAL_STORAGE_REQUEST = 2;
private int mState;
private static LruCache<String, Bitmap> mMemoryCache;
private HandlerThread mBackgroundThread;
private final Handler mUIHandler = new Handler(Looper.getMainLooper()){
#Override
public void handleMessage(Message msg){
swapImageAdapter();
}
};
private static File mImageFile;
private Handler mBackgroundHandler;
private TextureView mTextureView;
private Button mCaptureButton;
private File mImageFolder;
private static String mImageFileName;
private Size mPreviewSize; //mImageSize
private RecyclerView mRecycleView;
private String mCameraId;
private CameraDevice mCameraDevice;
private CaptureRequest mPreviewCaptureRequest;
private CaptureRequest.Builder mPreviewCaptureRequestBuilder;
private CameraCaptureSession mCameraCaptureSession;
private ImageReader mImageReader;
private ImageReader.OnImageAvailableListener mOnImageAvailableListener =
new ImageReader.OnImageAvailableListener(){
#Override
public void onImageAvailable(ImageReader reader){
Log.i(TAG,"OnImageAvailableListener!!!");
mBackgroundHandler.post(new
ImageSaver(reader.acquireNextImage(),mUIHandler));
}
};
private static class ImageSaver implements Runnable{
private final Image mImage;
private final Handler mHandler;
ImageSaver(Image image){
Log.i(TAG,"imgSaver const");
mImage=image;
mHandler=null;
}
ImageSaver(Image image,Handler handler){
Log.i(TAG,"imgSaver const");
mImage =image;
mHandler =handler;
}
#Override
public void run(){
Log.i(TAG,"In ImageSaver run()");
ByteBuffer byteBuffer=mImage.getPlanes()[0].getBuffer();
byteBuffer.rewind();
byte[] bytes = new byte[byteBuffer.capacity()];
byteBuffer.get(bytes);
FileOutputStream fileOutputStream = null;
try{
fileOutputStream =new FileOutputStream(mImageFileName);
fileOutputStream.write(bytes);
}catch(IOException e){
e.printStackTrace();
}
finally{
Log.i(TAG,"Closing Image!!");
mImage.close();
if(fileOutputStream!=null){
try {
fileOutputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
Message message = mHandler.obtainMessage();
Log.i(TAG,"sending Message from Image Saver run()");
message.sendToTarget();
}
}
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback
= new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
Log.i(TAG,"mSessionCaptureCallback+ onCaptureStarted");
}
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result){
super.onCaptureCompleted(session,request,result);
Log.i(TAG,"mSessionCaptureCallback+ onCaptureCompleted");
process(result); //process the result once capture session request is completed.
Log.i(TAG,"mSessionCaptureCallback+ onCaptureCompleted ENDS!");
}
#Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure){
super.onCaptureFailed(session, request, failure);
Toast.makeText(getApplicationContext(),"Focus Lock UnSucessfull!", Toast.LENGTH_SHORT).show();
}
private void process(CaptureResult result){
Log.i(TAG,"mSTATE_PICTURE_CAPTURED"+mState);
switch (mState){
case STATE_PREVIEW:
break;
case STATE_WAIT_AF_LOCK:
Log.i(TAG,"process_ wait_AF_LOCK");
Integer afState=result.get(CaptureResult.CONTROL_AF_STATE);
if(afState==CaptureRequest.CONTROL_AF_STATE_FOCUSED_LOCKED || afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED){
Log.i(TAG,"Lock Sucessfull!");
Toast.makeText(getApplicationContext(),"Lock Sucessfull!", Toast.LENGTH_SHORT).show();
mState=STATE_PICTURE_CAPTURED;
captureStillImage();
}
Log.i(TAG,"Out of process_WAIT_AF_LOCK");
break;
case STATE_PICTURE_CAPTURED:
break;
}
}
};
private CameraDevice.StateCallback mCameraDeviceStateCallback
= new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice cameraDevice) {
Log.i(TAG,"CameraDeviceStateCallback+ onOpened");
mCameraDevice = cameraDevice;
Toast.makeText(getApplicationContext(), "Cam Opened!", Toast.LENGTH_SHORT).show();
createCameraPreviewSession();
}
#Override
public void onClosed(CameraDevice dev){
mCameraDevice=null;
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
Log.i(TAG,"CameraDeviceStateCallback+ onDisconnected");
cameraDevice.close();
mCameraDevice = null;
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int error) {
cameraDevice.close();
mCameraDevice = null;
Log.i(TAG, "Error Number:" + error + "While opening camera!!!");
}
};
private TextureView.SurfaceTextureListener mSurfaceTexture = new
TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.i(TAG, "SurfaceTexture Available");
setupCamera(width, height);
Log.i(TAG, "in onSurfaceTextureAvailable ");
transformImage(width, height);
Log.i(TAG, "in onSurfaceTextureAvailable ");
openCamera();
Log.i(TAG, "in onSurfaceTextureAvailable ");
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Log.i(TAG, "in onSurfaceTextureSizeChanged ");
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
Log.i(TAG, "in onSurfaceTextureTextureUpdated");
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.i(TAG, "SurfaceTexture Destroyed");
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
createImageFolder();
setContentView(R.layout.activity_main);
if(ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED) {
mRecycleView = (RecyclerView) findViewById(R.id.galleryRecyclerView);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 1);
mRecycleView.setLayoutManager(gridLayoutManager);
RecyclerView.Adapter imageAdapter = new ImageAdapter(mImageFolder);
Log.i(TAG, "RecyclerViewSetup!");
mTextureView = (TextureView) findViewById(R.id.textureView);
Log.i(TAG, "TextureViewSetup!");
mCaptureButton = (Button) findViewById(R.id.captureButton);
mCaptureButton.setOnClickListener(this);
}
else{
if(shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_READ_EXTERNAL_STORAGE_REQUEST);
}
}
Log.i(TAG,"onCreate Completed");
}
#Override
public void onResume() {
super.onResume();
openBackgroundThread();
if (mTextureView.isAvailable()) {
setupCamera(mTextureView.getWidth(), mTextureView.getHeight());
transformImage(mTextureView.getWidth(),mTextureView.getHeight());
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
openCamera();
}
else {
if(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
Toast.makeText(this, "App needs to be able to save Images", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION_RESULT);
}
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTexture);
}
}
#Override
public void onPause() {
closeCamera();
closeBackgroundThread();
super.onPause();
}
public void setupCamera(int width, int height) {
Log.i(TAG,"setupcam");
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);
Size largestImageSize = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
new Comparator<Size>() {
#Override
public int compare(Size size, Size t1) {
return Long.signum(size.getWidth()*size.getHeight()- t1.getWidth()*t1.getHeight());
}
}
);
mImageReader = ImageReader.newInstance(largestImageSize.getWidth(),largestImageSize.getHeight(),ImageFormat.JPEG,1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener,mBackgroundHandler);
mPreviewSize = getPrefferedPreviewSize(map.getOutputSizes(SurfaceTexture.class), width, height);
mCameraId = cameraId;
Log.i(TAG,"Setup Camera Ends!!");
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private Size getPrefferedPreviewSize(Size[] mapSizes, int width, int height) {
List<Size> collectorSizes = new ArrayList<>();
for (Size size : mapSizes) {
if (width > height) {
if (size.getWidth() > width && size.getHeight() > height) {
collectorSizes.add(size);
} else {
if (size.getWidth() > height && size.getHeight() > width) {
collectorSizes.add(size);
}
}
}
}
if (collectorSizes.size() > 0) {
return Collections.min(collectorSizes, new Comparator<Size>() {
#Override
public int compare(Size lhs, Size rhs) {
return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getHeight() * rhs.getWidth());
}
});
}
return mapSizes[0];
}
public void openCamera() {
Log.i(TAG,"In OpenCamera");
CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
try {
Log.i(TAG,"CamaeraManager.OpenCamera");
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
Log.i(TAG,"CamaeraManager.OpenCameraEnds");
}
catch(SecurityException s){
s.printStackTrace();
}
catch(CameraAccessException e){
e.printStackTrace();
}
Log.i(TAG,"OpenCamera Ends");
}
public void closeCamera(){
if(mImageReader!=null){
mImageReader.close();
mImageReader=null;
}
if(mCameraCaptureSession!=null) {
mCameraCaptureSession.close();
mCameraCaptureSession = null;
}
if(mCameraDevice!=null){
mCameraDevice.close();
mCameraDevice = null;
}
}
public void createCameraPreviewSession(){
try{
Log.i(TAG,"CREATE_PREVIEW_CAMERA_SESSION");
SurfaceTexture surfaceTexture=mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
mPreviewCaptureRequestBuilder=mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewCaptureRequestBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(
Arrays.asList(previewSurface,mImageReader.getSurface()),
new CameraCaptureSession.StateCallback(){
#Override
public void onConfigured(CameraCaptureSession session){
Log.i(TAG,"mCameraDevice.careateCaptireSession onConfigured");
if(null == mCameraDevice){
return;
}
try{
mPreviewCaptureRequest=mPreviewCaptureRequestBuilder.build();
mCameraCaptureSession = session;
mCameraCaptureSession.setRepeatingRequest(mPreviewCaptureRequest,mSessionCaptureCallback,mBackgroundHandler);
}
catch(CameraAccessException e){
e.printStackTrace();
}
Log.i(TAG,"mCameraDevice.careateCaptireSession onConfigured setRepeatingRequests");
}
#Override
public void onConfigureFailed(CameraCaptureSession session){
Log.i(TAG,"mCameraDevice.careateCaptireSession onConfigurationFailed");
Toast.makeText(getApplicationContext(),"CreateCameraSession FAILED!!",Toast.LENGTH_SHORT).show();
}
}
,null);
}catch(CameraAccessException e){
e.printStackTrace();
}
}
private void clickPic(){
Log.i(TAG,"in ClickPic");
lockFocus();
Log.i(TAG,"exiting ClickPic");
}
private void lockFocus(){
try {
Log.i(TAG,"lockFocus");
mState = STATE_WAIT_AF_LOCK;
mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_START);
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(), mSessionCaptureCallback, mBackgroundHandler);
}catch(CameraAccessException e){
e.printStackTrace();
}
Log.i(TAG,"exiting lockFocus");
}
private void unlockFocus(){
try {
Log.i(TAG,"unlockFocus");
mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),mSessionCaptureCallback,mBackgroundHandler);
mState = STATE_PREVIEW;
mCameraCaptureSession.setRepeatingRequest(mPreviewCaptureRequestBuilder.build(), mSessionCaptureCallback, mBackgroundHandler);
}catch(CameraAccessException e){
e.printStackTrace();
}
Log.i(TAG,"exiting lockFocus");
}
private void openBackgroundThread(){
mBackgroundThread=new HandlerThread("Camera Background Thread");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper()) {
public void handleMessage(Message msg) {
Log.i(TAG,"Inside Background Handler");
}
};
}
private void closeBackgroundThread(){
Log.i(TAG,"closing Background Thread!");
mBackgroundThread.quitSafely();
try{
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
}catch(InterruptedException e){
e.printStackTrace();
}
}
private void captureStillImage(){
try {
Log.i(TAG,"captureStillImage");
mPreviewCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
mPreviewCaptureRequestBuilder.addTarget(mImageReader.getSurface());
int rotation = getWindowManager().getDefaultDisplay().getRotation();
mPreviewCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
CameraCaptureSession.CaptureCallback captureCallback =
new CameraCaptureSession.CaptureCallback(){
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result){
Log.i(TAG,"captureStillImage+ onCaptureCompleted"+mImageFileName);
Toast.makeText(getApplicationContext(),"Image Captured!",Toast.LENGTH_SHORT).show();
unlockFocus();
}
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
Log.i(TAG,"captureStillImage+ onCapturestarted");
try {
mImageFile=createImageFileName();
} catch (IOException e) {
e.printStackTrace();
}
}
};
CameraCaptureSession.stopRepeating();
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),captureCallback,null);
}catch(CameraAccessException e){
e.printStackTrace();
}
Log.i(TAG,"captureStillImage Ends!");
}
private void transformImage(int width,int height){
Matrix matrix = new Matrix();
if(mPreviewSize==null||mTextureView==null) {
return;
}
int rotation = getWindowManager().getDefaultDisplay().getRotation();
RectF textureRectF = new RectF(0,0,width,height);
RectF previewRectF = new RectF(0,0,mPreviewSize.getHeight(),mPreviewSize.getWidth());
float centerX = textureRectF.centerX();
float centerY = textureRectF.centerY();
if(rotation==Surface.ROTATION_90||rotation==Surface.ROTATION_270){
previewRectF.offset(centerX - previewRectF.centerX(),centerY-previewRectF.centerY());
matrix.setRectToRect(textureRectF,previewRectF,Matrix.ScaleToFit.FILL);
float scale = Math.max((float)width/mPreviewSize.getWidth(),
(float)height/mPreviewSize.getHeight());
matrix.postScale(scale,scale,centerX,centerY);
matrix.postRotate(90*(rotation-2),centerX,centerY);
}
mTextureView.setTransform(matrix);
}
#Override
public void onClick(View view){
switch(view.getId()){
case R.id.captureButton:
clickPic();
break;
}
}
private void checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
try {
createImageFileName();
} catch (IOException e) {
e.printStackTrace();
}
}
else {
if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "App needs to be able to save Images", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT);
}
}
private void createImageFolder() {
Log.i(TAG,"createImageFolder");
File imageFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
mImageFolder = new File(imageFile, "camera2Api");
if(!mImageFolder.exists()) {
mImageFolder.mkdirs();
}
}
private File createImageFileName() throws IOException {
Log.i(TAG,"createImageFileName");
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "IMG_" + timestamp + "_";
File imageFile = File.createTempFile(prepend, ".jpg", mImageFolder);
mImageFileName = imageFile.getAbsolutePath();
Log.i(TAG,"Image FILE NAME="+mImageFileName);
return imageFile;
}
#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(requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,
"Permission successfully granted!", Toast.LENGTH_SHORT).show();
}
}
if(requestCode==REQUEST_READ_EXTERNAL_STORAGE_REQUEST){
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,
"Permission successfully granted!", Toast.LENGTH_SHORT).show();
}
}
}
private void swapImageAdapter(){
Log.i(TAG,"swapImageAdapter"+mImageFolder.toString()+"mGalleryFolder from MainActivity!!");
RecyclerView.Adapter newImageAdapter=new ImageAdapter(mImageFolder);
mRecycleView.swapAdapter(newImageAdapter,false);
}
private File[] sortFilesToLatest(File fileImagesDir) {
File[] files = fileImagesDir.listFiles();
Arrays.sort(files, new Comparator<File>() {
#Override
public int compare(File lhs, File rhs) {
return Long.valueOf(rhs.lastModified()).compareTo(lhs.lastModified());
}
});
return files;
}
}
And this is the ImageAdapter class used to inflate the ImageViews in the RecyclerView:-
public class ImageAdapter extends RecyclerView.Adapter {
private static final String TAG="ImageAdapter";
private File imagesFile;
public ImageAdapter(File folderFile) {
Log.i(TAG,folderFile.toString()+"printing Folder File FROM IMAGE_ADAPTER!!!!");
imagesFile = folderFile;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i(TAG,"onCreateViewHolder");
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_image, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.i(TAG,"onBindViewHolder");
BitmapFactory.Options mBitOptions = new BitmapFactory.Options();
mBitOptions.inScaled=true;
mBitOptions.inSampleSize=2;
int size = imagesFile.listFiles().length;
Log.i(TAG,imagesFile.toString()+" its SIZE="+size+" position="+position);
Log.i(TAG,"CONSIDERING FILE:"+imagesFile.listFiles()[position].getPath());
File imageFile = imagesFile.listFiles()[position];
Bitmap imageBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(),mBitOptions);
holder.getImageView().setImageBitmap(imageBitmap);
}
#Override
public int getItemCount() {
Log.i(TAG,"getItemCount");
return imagesFile.listFiles().length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
public ViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.imageGalleryView);
}
public ImageView getImageView() {
return imageView;
}
}
}
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/galleryRecyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/captureButton"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="25dp"
android:layout_marginTop="28dp"
android:layout_toStartOf="#+id/captureButton" />
<Button
android:id="#+id/captureButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:text="#string/CaptureButtonString" />
<TextureView
android:id="#+id/textureView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
Activity_image.xml contains an ImageView in a RelativeLayout. I could not provide code for it due to character restrictions.
Please advise what am I doing wrong?
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
Hi aim working n android application to detect page number using camera preview.
After i received frame from OnPreviewFrame i'm doing real time image processing using opencv to find page number position .Now my question is How can i draw rectangle on surface View ?
Use this code
PreviewDemo.java
public class PreviewDemo extends Activity implements OnClickListener {
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
ImageView image;
Bitmap bmp, itembmp;
static Bitmap mutableBitmap;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
File imageFileName = null;
File imageFileFolder = null;
private MediaScannerConnection msConn;
Display d;
int screenhgt, screenwdh;
ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preview);
image = (ImageView) findViewById(R.id.image);
preview = (SurfaceView) findViewById(R.id.surface);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
previewHolder.setFixedSize(getWindow().getWindowManager()
.getDefaultDisplay().getWidth(), getWindow().getWindowManager()
.getDefaultDisplay().getHeight());
}
#Override
public void onResume() {
super.onResume();
camera = Camera.open();
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size: parameters.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);
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(PreviewDemo.this, t.getMessage(), Toast.LENGTH_LONG)
.show();
}
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
camera.startPreview();
inPreview = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
public void onPictureTaken(final byte[] data, final Camera camera) {
dialog = ProgressDialog.show(PreviewDemo.this, "", "Saving Photo");
new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (Exception ex) {}
onPictureTake(data, camera);
}
}.start();
}
};
public void onPictureTake(byte[] data, Camera camera) {
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
savePhoto(mutableBitmap);
dialog.dismiss();
}
class SavePhotoTask extends AsyncTask < byte[], String, String > {#Override
protected String doInBackground(byte[]...jpeg) {
File photo = new File(Environment.getExternalStorageDirectory(), "photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return (null);
}
}
public void savePhoto(Bitmap bmp) {
imageFileFolder = new File(Environment.getExternalStorageDirectory(), "Rotate");
imageFileFolder.mkdir();
FileOutputStream out = null;
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH)) + fromInt(c.get(Calendar.DAY_OF_MONTH)) + fromInt(c.get(Calendar.YEAR)) + fromInt(c.get(Calendar.HOUR_OF_DAY)) + fromInt(c.get(Calendar.MINUTE)) + fromInt(c.get(Calendar.SECOND));
imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
scanPhoto(imageFileName.toString());
out = null;
} catch (Exception e) {
e.printStackTrace();
}
}
public String fromInt(int val) {
return String.valueOf(val);
}
public void scanPhoto(final String imageFileName) {
msConn = new MediaScannerConnection(PreviewDemo.this, new MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
msConn.scanFile(imageFileName, null);
Log.i("msClient obj in Photo Utility", "connection established");
}
public void onScanCompleted(String path, Uri uri) {
msConn.disconnect();
Log.i("msClient obj in Photo Utility", "scan completed");
}
});
msConn.connect();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) {
onBack();
}
return super.onKeyDown(keyCode, event);
}
public void onBack() {
Log.e("onBack :", "yes");
camera.takePicture(null, null, photoCallback);
inPreview = false;
}
#Override
public void onClick(View v) {
}
}
Preview.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.view.SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Add the Permissions also
I need to create an app where when I click a photo it will save 3 jpegs is different focus modes(auto focus, Macro focus and Infinite focus) if possible and save it. I have made a basic camera app whoe code I am posting..Can you guys tell me how to implement this?
public class MainActivity extends Activity implements Constants,SurfaceHolder.Callback,Camera.PreviewCallback,
Camera.AutoFocusCallback, OnTouchListener{
private ViewFlipper myviewflipper;
private float initialXpoint;
private Camera mCamera;
private SurfaceView mPreviewSV;
private SurfaceHolder mSurfaceHolder;
private Button mCapture;
private Button mChange;
private Button mReturn;
private Button mLoad;
private ImageView mImageView;
private int mPicturesCaptured = 0;
boolean isCaptureClicked = false;
boolean encodingCompleted = false;
long startTime;
int currentFile = 0;
int initialPointer = -1;
int secondPointer = -1;
int direction = -1;
CameraSize picSize = BACK_CAM_PREVIEW_SIZE_3 ;
File mFile;
ArrayList<String> imagePath;
ProgressDialog mEncodingProgress;
DisplayTask mTask;
Bitmap mDisplayBitmap;
File path;
File[] files;
#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_main);
mFile = new File(Constants.Cameraeffect);
if (!mFile.exists())
mFile.mkdir();
setupUI();
}
private void setupUI()
{
mPreviewSV = (SurfaceView) findViewById(R.id.sv_cam_preview);
mCapture = (Button) findViewById(R.id.button_capture);
mChange = (Button) findViewById(R.id.toggle);
mReturn = (Button) findViewById(R.id.button_return);
mImageView = (ImageView) findViewById(R.id.display);
mImageView.setOnTouchListener(this);
mLoad = (Button) findViewById(R.id.button_load);
mSurfaceHolder = mPreviewSV.getHolder();
mSurfaceHolder.addCallback(this);
mCapture.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
deleteFiles();
mPicturesCaptured = 0;
isCaptureClicked = true;
startTime=System.currentTimeMillis();
progressUpdate();
}
});
mChange.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
int res = getCurrentCameraId();
switch(res){
case 0:
stopCamera();
startCamera(Constants.FRONT_CAMERA);
break;
case 1:
stopCamera();
startCamera(Constants.BACK_CAMERA);
break;
}
}
});
mLoad.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
imagePath=ListAllFiles();
mImageView.bringToFront();
mImageView.setVisibility(View.VISIBLE);
mImageView.setImageBitmap(decodeFile(imagePath.get(0)));
mTask = new DisplayTask();
mTask.execute("");
}
});
mReturn.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = getIntent();
finish();
startActivity(intent);
}
});
}
private ArrayList<String> ListAllFiles() {
ArrayList<String> tFileList = new ArrayList<String>();
path= new File(Constants.Cameraeffect);
if( path.exists() ) {
files = path.listFiles();
for(int i=0; i<files.length; i++) {
tFileList.add(files[i].toString());
}
}
return tFileList;
}
public void deleteFiles() {
path= new File(Constants.Cameraeffect);
if( path.exists() ) {
files = path.listFiles();
for(int i=0; i<files.length; i++) {
files[i].delete();
}
}
}
#SuppressWarnings("unused")
int getCurrentCameraId() {
int mCameraId = -1;
CameraInfo ci = new CameraInfo();
for (int i = 0 ; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, ci);
if (ci.facing == CameraInfo.CAMERA_FACING_BACK){
return Constants.BACK_CAMERA;
}
else if (ci.facing == CameraInfo.CAMERA_FACING_FRONT){
return Constants.FRONT_CAMERA;
}
}
return -1;
}
private void progressUpdate()
{
mEncodingProgress = new ProgressDialog(this);
mEncodingProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mEncodingProgress.setMessage("Encoding");
mEncodingProgress.setIndeterminate(false);
mEncodingProgress.show();
new Thread(new Runnable()
{
public void run()
{
while((System.currentTimeMillis()-startTime)<=5000)
{
try
{
Thread.sleep(10);
mEncodingProgress.setProgress(mPicturesCaptured + 1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start();
}
#SuppressWarnings("unused")
private void startCamera(int id)
{
try
{
if (mCamera != null)
stopCamera();
mCamera = Camera.open(id);
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(1280,720);
parameters.setFocusMode("infinite");
parameters.setJpegQuality(100);
parameters.setAutoExposureLock(true);
parameters.setAutoWhiteBalanceLock(true);
parameters.setRotation(0);
mCamera.setDisplayOrientation(0);
mCamera.setParameters(parameters);
mCamera.setPreviewCallback(this);
mCamera.setPreviewDisplay(mPreviewSV.getHolder());
mCamera.startPreview();
}
catch (IOException e)
{
stopCamera();
}
}
private void stopCamera()
{
if (mCamera != null)
{
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mPreviewSV.getHolder().removeCallback(this);
mCamera.release();
mCamera = null;
}
}
#Override
protected void onStart()
{
super.onStart();
}
#Override
protected void onResume()
{
super.onResume();
}
#Override
protected void onPause()
{
stopCamera();
super.onPause();
}
#Override
protected void onDestroy()
{
stopCamera();
super.onDestroy();
}
public void surfaceCreated(SurfaceHolder holder)
{
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
startCamera(0);
}
public void surfaceDestroyed(SurfaceHolder holder)
{
}
public void onPreviewFrame(byte[] data, Camera camera)
{
if (System.currentTimeMillis()-startTime<=5000)
{
savingJpegToSDCard(data);
}
else
{
if(mEncodingProgress!=null){
mEncodingProgress.dismiss();
mEncodingProgress=null;
encodingCompleted=true;
}
}
if(encodingCompleted){
/*
* Log.i("","sent to JNI");
*/
encodingCompleted=false;
}
}
public void onAutoFocus(boolean arg0, Camera arg1) {
// TODO Auto-generated method stub
}
public boolean onTouch(View arg0, MotionEvent event) {
Log.d("","srikrishna:: ontouch");
switch(event.getAction()){
case(MotionEvent.ACTION_DOWN):
initialPointer=(int) event.getX();
break;
case(MotionEvent.ACTION_MOVE):
secondPointer=(int) event.getX();
break;
case(MotionEvent.ACTION_UP):
initialPointer=(int) event.getX();
}
return true;
}
public Bitmap decodeFile(String fPath)
{
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
opts.inDither = false;
opts.inPurgeable = true;
opts.inInputShareable = true;
BitmapFactory.decodeFile(fPath, opts);
final int REQUIRED_SIZE = 500;
int scale = 1;
if (opts.outHeight > REQUIRED_SIZE || opts.outWidth > REQUIRED_SIZE)
{
final int heightRatio = Math
.round((float) opts.outHeight / (float) REQUIRED_SIZE);
final int widthRatio = Math
.round((float) opts.outWidth / (float) REQUIRED_SIZE);
scale = heightRatio < widthRatio ? heightRatio : widthRatio;//
}
opts.inJustDecodeBounds = false;
opts.inSampleSize = scale;
Bitmap bm = BitmapFactory.decodeFile(fPath, opts).copy(
Bitmap.Config.RGB_565, false);
return bm;
}
private void savingJpegToSDCard(final byte[] b1)
{
try{
Camera.Parameters parameters = mCamera.getParameters();
Size size = parameters.getPreviewSize();
Log.i("","abh size width and height "+size.width + " "+size.height);
YuvImage image = new YuvImage(b1, parameters.getPreviewFormat(),size.width, size.height, null);
File file = new File(Constants.Cameraeffect + "/File" + mPicturesCaptured + ".jpeg");
FileOutputStream filecon = new FileOutputStream(file);
image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 90,filecon);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
mPicturesCaptured++;
}
class DisplayTask extends AsyncTask<String, Bitmap, Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
currentFile = 0;
}
#Override
protected Void doInBackground(String... params)
{
while(true){
Log.i("","abh imagePath.size() "+imagePath.size());
if(secondPointer-initialPointer >50)
{
Log.i("","abh currentFile "+currentFile);
mDisplayBitmap = decodeFile(imagePath.get(currentFile));
publishProgress(mDisplayBitmap);
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(currentFile<=90)
currentFile++;
initialPointer=secondPointer;
}
}
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Bitmap... values)
{
super.onProgressUpdate(values);
mImageView.setImageBitmap(values[0]);
}
}
}
In your start camera method set the focus mode to the required one and start the camera. If you want to change it dynamically on click of button then you must call the start camera method with the required attributes. Make sure you are releasing camera[this is very imp] also note that the custom camera implementation in android is very buggy[many of the bugs are stil open just goggle it and see] i suggest you read it carefully and implement it.
I am creating small app which previews camera and when clicking on screen saves image.
My problem is when image is saved, I want to start different activity which will do preview and have some tools on it. But what ever I do activity doesn't start.
Here is my code
public class CameraActivity extends Activity {
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
preview = (SurfaceView) findViewById(R.id.preview);
Button button = (Button) findViewById(R.id.button_capture);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (camera != null) {
camera.takePicture(null, null, photoCallback);
onPause();
Intent intent = new Intent(CameraActivity.this, PreviewAndSaveActivity.class);
intent.putExtra("image", "");
CameraActivity.this.startActivity(intent);
}
}
});
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
Camera.CameraInfo info = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
camera = Camera.open(i);
}
}
}
if (camera == null) {
camera = Camera.open();
}
startPreview();
}
#Override
public void onPause() {
if (camera != null) {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
}
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.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);
}
private Camera.Size getSmallestPictureSize(Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.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);
}
private void initPreview(int width, int height) {
if (camera != null && previewHolder.getSurface() != null) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(CameraActivity.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
if (!cameraConfigured) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
Camera.Size pictureSize = getSmallestPictureSize(parameters);
if (size != null && pictureSize != null) {
parameters.setPreviewSize(size.width, size.height);
parameters.setPictureSize(pictureSize.width,
pictureSize.height);
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
camera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview() {
if (cameraConfigured && camera != null) {
camera.startPreview();
inPreview = true;
}
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
};
Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
camera.takePicture(null, null, new PhotoHandler(
getApplicationContext()));
camera.startPreview();
inPreview = true;
}
};
}
And in PhotoHandler after decoding and saving image I want to start activity
public class PhotoHandler implements PictureCallback {
private final Context context;
public PhotoHandler(Context context) {
this.context = context;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Log.d("", "Can't create directory to save image.");
Toast.makeText(context, "Can't create directory to save image.",
Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "pic_" + date + ".jpg";
String pictureName = pictureFileDir.getPath() + File.separator
+ photoFile;
File pictureFile = new File(pictureName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(pictureFile);
fos.write(data);
Intent intent = new Intent(context, PreviewAndSaveActivity.class);
intent.putExtra("image", pictureName);
context.startActivity(intent);
} catch (Exception error) {
Toast.makeText(context, "Image could not be saved.",
Toast.LENGTH_LONG).show();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
}
}
}
}
private File getDir() {
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(sdDir, "dir");
}
}
Any suggestion what am I doing wrong?
try this code :
(Replace your button click listener )
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (camera != null) {
camera.takePicture(null, null, photoCallback);
onPause();
Intent intent = new Intent(CameraActivity.this, PreviewAndSaveActivity.class);
intent.putExtra("image", "");
CameraActivity.this.startActivityForResult(intent, 100);
}
}
});
In your CameraActivity add this callback method to redirect on another activity after image save :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
// start you new activity from here...
}
super.onActivityResult(requestCode, resultCode, data);
}