In my application I need to use custom camera. There are two buttons on the screen "Keep Image" and "Retake Photo". The picture taken by the cam should be saved in the specified directory when I click on the "keep image" button. When I click on "retake photo" button the cam should be ready to take a new photo. I have searched for the same and I got a Stack overflow link and I tried to implement that in my app, but the problem is all the code for taking picture and saving picture is written in the same class. The picture taken will be automatically saved without even a button click. I want to change that. I have tried different ways but throwing errors.
Please help me...given below is my java code
public class CustomCameraDemo extends Activity {
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
public 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;
Button save;
Button retake;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// image=(ImageView)findViewById(R.id.image);
save=(Button)findViewById(R.id.Save);
retake=(Button)findViewById(R.id.Retake);
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());
save.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
retake.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
#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(CustomCameraDemo.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) {
}
};
Camera.PictureCallback photoCallback=new Camera.PictureCallback(){
public void onPictureTaken(final byte[] data, final Camera camera){
dialog=ProgressDialog.show(CustomCameraDemo.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(),"MyMedicalRecords");
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(CustomCameraDemo.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;
}
}
given below is my main layout
<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"
/>
<Button android:layout_width="150dip"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Keep Photo"
android:id="#+id/Save"></Button>
<TextView android:layout_below="#+id/surface"
android:layout_width="wrap_content"
android:id="#+id/textView1"
android:layout_height="wrap_content"
android:text=""
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"></TextView>
<Button android:layout_width="150dip"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/textView1"
android:text="Retake Photo"
android:id="#+id/Retake"></Button> </RelativeLayout>
If you want to build over the existing code, you can just delete the saved image when the user opts to retake another image.
Related
Get picture from camera when object(any document)fully occupies the camera view inside the camera boundary. actually i have created custom camera and i want to get any object picture when picture fully come inside camera boundary.I have set the camera boundary inside the xml part.
This is my code please check and correct me fine out this problem.
public class MainActivity extends ActionBarActivity {
private ImageSurfaceView mImageSurfaceView;
private Camera camera;
public static FrameLayout cameraPreviewLayout;
private ImageView capturedImageHolder;
String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
cameraPreviewLayout = (FrameLayout) findViewById(R.id.camera_preview);
camera = checkDeviceCamera();
mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
cameraPreviewLayout.addView(mImageSurfaceView);
Button captureButton = (Button) findViewById(R.id.button);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camera.takePicture(null, null, pictureCallback);
}
});
}
private Camera checkDeviceCamera() {
Camera mCamera = null;
try {
mCamera = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
return mCamera;
}
PictureCallback pictureCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();;
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
Log.e("mediaFile",""+mediaFile.length());
return mediaFile;
}
}
This is the xml file.
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="400dp"
android:layout_height="320dp"
android:background="#drawable/camera_backround"
android:padding="10dp"
android:layout_margin="10dp"
>
</FrameLayout>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/capture_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
This is my SurfaceView class.
public class ImageSurfaceView extends SurfaceView implements SurfaceHolder.Callback,Camera.PictureCallback, Camera.PreviewCallback {
private Camera camera;
private SurfaceHolder surfaceHolder;
Context context;
private boolean mFocused;
private boolean imageProcessorBusy=true;
private int width;
private int height;
public void setImageProcessorBusy(boolean imageProcessorBusy) {
this.imageProcessorBusy = imageProcessorBusy;
}
public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
this.surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.context=context;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera.setDisplayOrientation(90);
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
Log.e("camera", "surfaceChanged");
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e("camera","surfaceDestroyed");
this.camera.stopPreview();
this.camera.setPreviewCallback(null);
this.camera.release();
this.camera = null;
}
private void refreshCamera() {
try {
Log.e("camera", "refreshCamera");
camera.stopPreview();
} catch (Exception e) {
}
try {
Log.e("camera", "refreshCamera----2");
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
camera.setPreviewCallback(this);
} catch (Exception e) {
}
}
#Override
public void onPictureTaken(byte[] bytes, Camera camera) {
android.hardware.Camera.Size pictureSize = camera.getParameters().getPictureSize();
Log.d("Check", "onPictureTaken - received image " + pictureSize.width + "x" + pictureSize.height);
}
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
android.hardware.Camera.Size pictureSize = camera.getParameters().getPreviewSize();
// layout in the activity that the cameraView will placed in
int layoutWidth = MainActivity.cameraPreviewLayout.getWidth();
int layoutHeight = MainActivity.cameraPreviewLayout.getHeight();
Log.e("layoutWidth","------"+layoutWidth);
Log.e("layoutHeight", "---------" + layoutHeight);
Log.d("onPreviewFrame", "onPreviewFrame - received image " + pictureSize.width + "x" + pictureSize.height
+ " focused: "+ mFocused +" imageprocessor: "+(imageProcessorBusy?"busy":"available"));
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = width;
setMeasuredDimension(width, width);
}
}
you can use intent to capture the image data from camera, try this
private static final int TAKE_PICTURE = 1000;
private Uri imageUri;
In your button click
Button captureButton = (Button) findViewById(R.id.button);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePhoto();
}
});
public void takePhoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(intent, TAKE_PICTURE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PICTURE:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
ImageView imageView = (ImageView) findViewById(R.id.ImageView);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(cr, selectedImage);
imageView.setImageBitmap(bitmap);
Toast.makeText(this, selectedImage.toString(),
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
.show();
Log.e("Camera", e.toString());
}
}
}
}
Your xml code
<ImageView
android:id="#+id/Imageview"
android:layout_width="400dp"
android:layout_height="320dp"
android:background="#drawable/camera_backround"
android:padding="10dp"
android:layout_margin="10dp"
/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/capture_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
Note: if you are going to take multiple pictures append timestamp to the filename.
I made app that takes picture when button is pressed and another app that records 3 second video when you open app.I want to start recording video immediately after I press Capture button.When I try to connect capturing and recording in one app It always crash.
How to connect this two codes and make it capture video after capturing image ?
this is code for taking and saving picture when button is pressed
public class PreviewActivity extends Activity implements
SurfaceHolder.Callback, Camera.ShutterCallback, Camera.PictureCallback {
Camera mCamera;
SurfaceView mPreview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mPreview = (SurfaceView)findViewById(R.id.preview);
mPreview.getHolder().addCallback(this);
mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCamera = Camera.open();
}
#Override
public void onPause() {
super.onPause();
mCamera.stopPreview();
}
#Override
public void onDestroy() {
super.onDestroy();
mCamera.release();
Log.d("CAMERA", "Destroy");
}
public void onCancelClick(View v) { // this is from Cancel Button
finish();
}
public void onSnapClick(View v) { // this is from Capture button
mCamera.takePicture(null, null, this);
}
#Override
public void onShutter() {
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//Here, we chose internal storage
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
//write the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
camera.startPreview();
}
private static File getOutputMediaFile() {
//make a new file directory inside the "sdcard" folder
File mediaStorageDir = new File("/sdcard/", "Taken Picture");
//if this "JCGCamera folder does not exist
if (!mediaStorageDir.exists()) {
//if you cannot make this folder return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
//take the current timeStamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
//and make a media file:
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters=mCamera.getParameters();
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
mCamera.setDisplayOrientation(90);
parameters.set("rotation",90);
//parameters.set("orientation", "portrait");
Log.i("alengenije","portrait");
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
parameters.set("rotation", 0);
//parameters.set("orientation", "landscape");
Log.i("alengenije", "landscape");
}
mCamera.setParameters(parameters);
mCamera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mPreview.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("PREVIEW","surfaceDestroyed");
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="#+id/preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="100dip"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:background="#A000">
<Button
android:layout_width="100dip"
android:layout_height="wrap_content"
android:text="Cancel"
android:onClick="onCancelClick"
/>
<Button
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Snap Photo"
android:onClick="onSnapClick"
/>
</RelativeLayout>
</RelativeLayout>
This is code for recording video for 3 seconds:
public class VideoCapture extends SurfaceView implements SurfaceHolder.Callback {
private MediaRecorder recorder;
private SurfaceHolder holder;
public Context context;
private Camera camera;
public static String videoPath = Environment.getExternalStorageDirectory()
.getPath() +"/YOUR_VIDEO.mp4";
public VideoCapture(Context context) {
super(context);
this.context = context;
init();
}
public VideoCapture(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public VideoCapture(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
#SuppressLint("NewApi")
public void init() {
try {
recorder = new MediaRecorder();
recorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
Log.i("alengenije", "video END");
recorder.stop();
}
}
});
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera = getCameraInstance();
camera.unlock();
recorder.setCamera(camera);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setMaxDuration(3000);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setOutputFile(videoPath);
} catch (Exception e) {
e.printStackTrace();
}
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder mHolder) {
try {
recorder.setPreviewDisplay(mHolder.getSurface());
recorder.prepare();
recorder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopCapturingVideo() {
try {
recorder.stop();
camera.lock();
} catch (Exception e) {
e.printStackTrace();
}
}
#TargetApi(5)
public void surfaceDestroyed(SurfaceHolder arg0) {
if (recorder != null) {
stopCapturingVideo();
recorder.release();
camera.lock();
camera.release();
recorder = null;
}
}
private Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c;
}
}
Can you start recording for 4 seconds & then take thumbnail from 1st second & rest is your video. This way you don't have to start camera twice.
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
My app requires that I take a picture, and the only device I'm running in problems with is the Motorola Razr. I've tried it on the Nexus One, Droid X, Droid 2, Sensation, and a few others. Here is the code I am using:
public class CameraView extends Activity {
private static final String TAG = "CameraView";
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
public Camera camera=null;
private boolean inPreview=false;
private ImageView takePicture;
private Uri uriTarget;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameraview);
takePicture = (ImageView)findViewById(R.id.take_picture);
preview=(SurfaceView)findViewById(R.id.preview);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder
.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
if (savedInstanceState != null)
{
uriTarget = savedInstanceState.getParcelable("uriTarget");
}
preview.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
takePicture.setEnabled(false);
camera.autoFocus(myAutoFocusCallback);
}
});
takePicture.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
//camera.takePicture(null, null, photoCallback);
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
inPreview=false;
}
});
}
#Override
public void onResume() {
super.onResume();
try{
if (camera==null) {
camera=Camera.open();
camera.setDisplayOrientation(90);
Camera.Parameters params = camera.getParameters();
params.set("rotation", 90);
params.setJpegQuality(60);
//params.setPictureSize(32, 32);
camera.setParameters(params);
}
}catch (Exception e){
finish();
}
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
if(camera != null)
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t) {
Log.e("PictureDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(CameraView.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
Camera.Parameters parameters=camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setJpegQuality(60);
parameters.set("rotation", 90);
camera.setParameters(parameters);
camera.startPreview();
inPreview=true;
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera1) {
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length);
Constants.showImage = true;
FileOutputStream outStream = null;
try {
File esd = Environment.getExternalStorageDirectory();
File newDirectory = new File(esd.getAbsolutePath() + "/DCIM/statefair/");
if(!newDirectory.exists())
newDirectory.mkdirs();
outStream = new FileOutputStream(esd.getAbsolutePath() + String.format(
"/DCIM/statefair/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO exception");
} finally {
System.out.println("Finally");
camera.release();
}
finish();
}
};
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){
#Override
public void onAutoFocus(boolean arg0, Camera arg1) {
// TODO Auto-generated method stub
takePicture.setEnabled(true);
}
};
protected void onSaveInstanceState(Bundle outState)
{
outState.putParcelable("uriTarget", uriTarget);
}
}
I get an outOfMemory error on this line:
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length);
even when I set the JPEG quality to 10. Anyone else run into this problem?
Check this BitmapFactory.Options
Full size images take a lot of memory, you should make re-size. Just for quick test, try this:
Options opts = new Options();
opts.inSampleSize = 4;
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
I want to use camera preview in an activity. I want to add images(transparent frames on surface view). I tried following code so that i can easily customize the xml layout desirably:
package com.demo;
import java.io.IOException;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
public class CameraDemoActivity extends Activity implements SurfaceHolder.Callback{
/** Called when the activity is first created. */
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera = Camera.open();
if(camera!=null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e) {
Toast.makeText(this, (CharSequence) e, Toast.LENGTH_LONG).show();
}
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".CameraDemoActivity"
android:label="#string/app_name" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android:hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>
And here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<SurfaceView
android:id="#+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Dont know why preview of camera is not displaying?
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
<?xml version="1.0" encoding="utf-8"?>
<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>
Use device Menu button to take picture.
Add the permissions in Manifest file
Check Rotate folder in Gallery for the captured image.