I want capture successive shooting with android camera to get HDR image using 2 image.
but my code is not working. My App is just shooting twice with no sound(no shutter sound), and no save file i have(there is no file).
First, I think that my file name was same. so, I changed my file file code like this,
// Create a media file name
// add .SSS for identity
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
Second, using synchronized and startPreview(). but still not work.
below is my capture code using "private Camera mCamera".
// Add a listener to the Capture button
captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
synchronized (mPicture) {
// get an image from the camera
Camera.Parameters cp = mCamera.getParameters();
cp.setExposureCompensation(cp.getMinExposureCompensation());
mCamera.setParameters(cp);
mCamera.takePicture(null, null, mPicture);
// if i delete below 5 line then work correctly(but, just one image i can get)
mCamera.startPreview();
cp.setExposureCompensation(cp.getMaxExposureCompensation());
mCamera.setParameters(cp);
mCamera.takePicture(null, null, mPicture);
mCamera.startPreview();
}
}
}
);
and below is picture callback method.
private PictureCallback mPicture = new PictureCallback() {
String TAG = "HDR_TAG";
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
Can you give me some advice?
Thanks.
(I'm sorry that my english skill is bad..)
you can get the image data continuously from camera by setting previewCallBack for camera.
camera.setPreviewCallback(previewCallback);
private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera cam) {
//get the image data here and save it..
}
};
I solved my problem using thread and endless while. See below.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
Thread t_1 = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Camera.Parameters cp = mCamera.getParameters();
cp.setAutoExposureLock(true);
mCamera.takePicture(null, null, mPicture);
}
});
Thread t_2 = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (takePicFlag != CAPTURE_SECOND)
;
Camera.Parameters cp = mCamera.getParameters();
cp.setExposureCompensation(cp
.getMinExposureCompensation());
mCamera.setParameters(cp);
mCamera.takePicture(null, null, mPicture);
}
});
Thread t_3 = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (takePicFlag != CAPTURE_THIRD)
;
Camera.Parameters cp = mCamera.getParameters();
cp.setExposureCompensation(cp
.getMaxExposureCompensation());
mCamera.setParameters(cp);
mCamera.takePicture(null, null, mPicture);
}
});
t_1.start();
t_2.start();
t_3.start();
}
});
}
and use some flag for capture.
see finally{ }.
final static String TAG = "HDR_TAG";
static int m_idenValue = 1; // 사진의 이름 중복을 방지하기위한 변수
byte[] pic_data_1;
byte[] pic_data_2;
byte[] pic_data_3;
final int CAPTURE_FIRST = 1;
final int CAPTURE_SECOND = 2;
final int CAPTURE_THIRD = 3;
int takePicFlag = CAPTURE_FIRST;
private PictureCallback mPicture = new PictureCallback() {
String TAG = "HDR_TAG";
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
// TODO Auto-generated method stub
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
} finally {
mCamera.startPreview();
if (takePicFlag == CAPTURE_FIRST)
{
pic_data_1 = data.clone();
Log.d(TAG, "onPictureTaken, data : " + data + "\ntakePicFalg : " + takePicFlag);
takePicFlag = CAPTURE_SECOND;
}
else if(takePicFlag == CAPTURE_SECOND)
{
pic_data_2 = data.clone();
Log.d(TAG, "onPictureTaken, data : " + data + "\ntakePicFalg : " + takePicFlag);
takePicFlag = CAPTURE_THIRD;
}
else
{
pic_data_3 = data.clone();
Log.d(TAG, "onPictureTaken, data : " + data + "\ntakePicFalg : " + takePicFlag);
takePicFlag = CAPTURE_FIRST;
}
}
}
};
Related
My application got crashed on devices with no SD cards in it, but is working fine with devices which are having SD card in it.When i debugged it, i found that on
mCamera.takePicture(null, null, jpegCallBack);
Method app is getting crashed with above error.I goggled a lot but didn't found any solution , i saw this link :-
http://forums.androidcentral.com/motorola-droid-x/102987-camera-won-t-take-pictures-without-sd-card.html
So is it possible to capture images in background service in device with no SD card in it.
Please provide me some clues
Here are some methods of my hiddenCamera class
#SuppressWarnings("deprecation")
private void startCapturingCall() {
final Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
if (mCamera != null) {
parameters = mCamera.getParameters();
if (FLASH_MODE == null || FLASH_MODE.isEmpty()) {
FLASH_MODE = "auto";
}
parameters.setFlashMode(FLASH_MODE);
pictureSize = getBiggesttPictureSize(parameters);
if (pictureSize != null)
parameters
.setPictureSize(pictureSize.width, pictureSize.height);
// set camera parameters
mCamera.setParameters(parameters);
mCamera.startPreview();
new Handler().postDelayed(new Runnable() {
#SuppressWarnings("deprecation")
#Override
public void run() {
if (isSDPresent) {
mCamera.takePicture(null, null, jpegCallBack);
} else {
Toast.makeText(getApplicationContext(),
"Please Insert SD card", 1000).show();
}
}
}, 2000);
}
}
#SuppressWarnings("deprecation")
Camera.PictureCallback jpegCallBack = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
// checking for SD card
if (isSDPresent) {
mediaStorageDir = new File(Environment
.getExternalStorageDirectory().getAbsolutePath(),
IMAGE_DIRECTORY_NAME);
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
}
}
try {
Bitmap userImage = BitmapFactory.decodeByteArray(data, 0,
data.length);
// set file out stream
FileOutputStream out = new FileOutputStream(mediaFile);
// set compress format quality and stream
userImage.compress(Bitmap.CompressFormat.JPEG, 50, out);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
userImage.compress(Bitmap.CompressFormat.JPEG, 50, baos);
mByteArray = baos.toByteArray();
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(),
"Please insert SD card !", Toast.LENGTH_LONG).show();
}
if (mediaStorageDir.exists()) {
getPathOfCapturedImage();
}
HiddenCamera.this.finish();
CameraService.IS_ACTIVITY_FINISHED = true;
}
};
And also isSDPresent always returns me true value .
Please provide me your suggestions on this. I am really stuck at this point from last 2-3 days.
This is the issue of Device too as in Samsung Grand , my code is working fine even its not having SD card in it.But in Moto E its my application getting crashed.Camera settings plays an important role in it.
Thanks
Finally i am done with this, though i got busy in some other task but today i get time to post my Answer on this topic, As this topis is very general , so i am posting this answer inorder to help others who might have thought of this functionality , So i done this thing by using SurfaceTexture but it will only work for versions greater thet 4 and for versions less than 4 you need to use surfaceView.
So here is my code :-
public class SurfaceTextureActivity extends Activity implements
SurfaceTextureListener {
private Parameters mParameters;
private Camera.Size mPictureSize;
private static final String sIMAGE_DIRECTORY_NAME = "HiddenCapturedPics";
private byte[] mByteArray;
private Camera mCamera;
private TextureView mTextureView;
private File mMediaFile, mMediaStorageDir = null;
private String mEncodedImage, mImageName, mFinalResponse,
mFlashMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextureView = new TextureView(this);
setContentView(mTextureView);
if (checkCameraHardware(getApplicationContext())) {
mTextureView.setSurfaceTextureListener(this);
Bundle extras = getIntent().getExtras();
mFlashMode = extras.getString("FLASH");
} else {
Toast.makeText(getApplicationContext(),
"Your Device dosen't have a Camera !", Toast.LENGTH_LONG)
.show();
}
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height) {
mCamera = Camera.open();
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(0, 0,
Gravity.CENTER));
try {
mCamera.setPreviewTexture(surface);
} catch (IOException t) {
}
mCamera.startPreview();
startCapturingCall();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height) {
// Ignored, the Camera does all the work for us
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.stopPreview();
mCamera.release();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
Toast.makeText(getApplicationContext(), "Dfg", Toast.LENGTH_SHORT)
.show();
// Update your view here!
}
Camera.PictureCallback jpegCallBack = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
// checking for SD card
if (isSDPresent) {
mMediaStorageDir = new File(Environment
.getExternalStorageDirectory().getAbsolutePath(),
sIMAGE_DIRECTORY_NAME);
mMediaFile = new File(mMediaStorageDir.getPath()
+ File.separator + "IMG_" + timeStamp + ".jpg");
if (!mMediaStorageDir.exists()) {
if (!mMediaStorageDir.mkdirs()) {
}
}
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap userImage = BitmapFactory.decodeByteArray(data, 0,
data.length, options);
FileOutputStream out = new FileOutputStream(mMediaFile);
userImage.compress(Bitmap.CompressFormat.JPEG, 50, out);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
userImage.compress(Bitmap.CompressFormat.JPEG, 50, baos);
mByteArray = baos.toByteArray();
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(),
"Please insert SD card !", Toast.LENGTH_LONG).show();
}
if (mMediaStorageDir.exists()) {
getPathOfCapturedImage();
}
SurfaceTextureActivity.this.finish();
CameraService.IS_ACTIVITY_FINISHED = true;
}
};
private void startCapturingCall() {
if (mCamera != null) {
mParameters = mCamera.getParameters();
if (mFlashMode == null || mFlashMode.isEmpty()) {
mFlashMode = "auto";
}
mParameters.setFlashMode(mFlashMode);
mPictureSize = getBiggesttPictureSize(mParameters);
if (mPictureSize != null)
mParameters.setPictureSize(mPictureSize.width,
mPictureSize.height);
mCamera.setParameters(mParameters);
mCamera.startPreview();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (mCamera != null) {
mCamera.startPreview();
mCamera.takePicture(null, null, jpegCallBack);
} else {
mCamera = getCameraInstance();
mCamera.startPreview();
mCamera.takePicture(null, null, jpegCallBack);
}
}
}, 2000);
}
}
private Camera.Size getBiggesttPictureSize(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);
}
public static 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; // returns null if camera is unavailable
}
}
Hope this will help others .......
Here are the links for reference :-
Example of Camera preview using SurfaceTexture in Android
Camera.takePicture throws RunTimeException
Cheers!!!!!
Following the documentation from developper.android.com
I wrote a short Activity to take picture from within the app.
I sometimes met this error :
02-23 17:37:06.323: E/IMemory(5003): binder=0x3c010388 transaction failed fd=-2147483647, size=0, err=-2147483646 (Unknown error: 2147483646)
02-23 17:37:06.328: E/IMemory(5003): cannot dup fd=-2147483647, size=0, err=-2147483646 (Bad file number)
02-23 17:37:06.328: E/IMemory(5003): cannot map BpMemoryHeap (binder=0x3c010388), size=0, fd=-1 (Bad file number)
can you help me understand it ?
Does setting the picture size to the smallest value retrieved from the getPictureSizes() method requieres less memory at the capture time or is it applied later ?
For information, here is my activitity (just the concatenation of the code example from this page ). Before that code, I used a very simplistic code with a preview and takePicture.
public class CatchImage extends Activity {
private boolean fgDebugLocal = true;
private String tagLocal = "CatchImage ";
private Button btTake, btRetour;
private Intent intent;
private String refPhoto;
private String strPath = "";
private String strFileName = "";
private Context context;
private CameraPreview mPreview;
private FrameLayout preview;
private Camera cameraCatchImage;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
context = getApplicationContext();
/**
* Set full screen
* Used in Landscape
*/
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Baseline.tepvLogger.stat(tagLocal, "init ");
setContentView(R.layout.camera);
/**
* get the id of picture
*/
intent = getIntent();
refPhoto = intent.getStringExtra("refPhoto");
strPath = intent.getStringExtra("strSdInternalPath");
StringBuilder sb = new StringBuilder();
sb.append(strPath);
sb.append(File.separatorChar);
sb.append(Params.PATH_REP_PHOTO);
sb.append(File.separatorChar);
sb.append(Params.PHOTO_FILE_NAME);
sb.append(refPhoto);
sb.append(Params.PHOTO_FILE_EXT_JPG);
strFileName = sb.toString();
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "strFileName = " + strFileName);};
btTake = (Button) findViewById(R.id.btStatCatchPictureTake);
btRetour = (Button) findViewById(R.id.btStatCatchPictureRetour);
btTake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "btTake");};
mPreview.mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
});
btRetour.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "btRetour ");};
Intent intent = new Intent(CatchImage.this, StationnementPhoto.class);
startActivity(intent);
finish();
}
});
}
#Override
public void onResume() {
super.onResume();
if (!checkCameraHardware(context)) {
afficheAlertDlg(getResources().getString(R.string.dlg_titre_alert), getResources().getString(R.string.catch_image_no_camera), getResources().getDrawable(R.drawable.ic_alert));
} else {
if (Camera.getNumberOfCameras()>1) {
new TePVException(this.getClass().getName(), "checkCameraHardware", "More than one camera detected");
}
if (safeCameraOpen(0)) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "safeCameraOpen(0) true : creating preview");};
btTake.setEnabled(true);
btTake.setBackgroundResource(R.drawable.bt_border_selector);
mPreview = new CameraPreview(context, cameraCatchImage);
preview = (FrameLayout) findViewById(R.id.flStatCatchPreview);
preview.addView(mPreview);
} else {
btTake.setEnabled(false);
btTake.setBackgroundResource(R.drawable.bt_border_disable);
}
}
}
#Override
public void onPause() {
super.onPause();
releaseCameraAndPreview(); // release the camera immediately on pause event
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCameraAndPreview();
cameraCatchImage = Camera.open(id);
qOpened = (cameraCatchImage != null);
} catch (Exception e) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "failed to open Camera");};
e.printStackTrace();
}
return qOpened;
}
private void releaseCameraAndPreview() {
if (mPreview!=null) mPreview.setCamera(null);
if (cameraCatchImage != null) {
cameraCatchImage.release();
cameraCatchImage = null;
}
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "shutterCallback ");};
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "rawCallback ");};
}
};
private PictureCallback jpegCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "jpegCallback ");};
FileOutputStream outStream = null;
try {
//String strFileNameComplet = strPath + File.separatorChar + strFileName + refPhoto + Params.PHOTO_FILE_EXT_JPG;
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "strFileName = " + strFileName);};
outStream = new FileOutputStream(strFileName);
outStream.write(data);
outStream.close();
File fileVerif = new File(strFileName);
if (fileVerif.exists()){
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "Photo stockée ");};
Intent intent = new Intent(CatchImage.this, StationnementPhoto.class);
startActivity(intent);
finish();
}else {
new TePVException("CatchImage", "PictureCallback", "Pb stockage image = " + strFileName);
Toast.makeText(context, "Erreur enregistrement de la photo, essayez à nouveau", Toast.LENGTH_LONG).show();
}
} catch (FileNotFoundException e) {
new TePVException("CatchImage", "PictureCallback", "FileNotFoundException = " + e.getMessage());
} catch (IOException e) {
new TePVException("CatchImage", "PictureCallback", "IOException = " + e.getMessage());
} finally {
}
}
};
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera object) {
mCamera = object;
}
public Camera getCamera() {
return mCamera;
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
if (Params.tagFgDebug && fgDebugLocal){Log.d(tagLocal, "Error setting camera preview: " + e.getMessage());}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
if (Params.tagFgDebug && fgDebugLocal){Log.d(tagLocal, "Error starting camera preview: " + e.getMessage());}
}
}
}
Edit : I saw this question but I already saved the image as a file.
I found a solution :
We stop using Camera camera.takePicture() and only use the preview object. Idea based on #CommonsWare code for the photo display and base on zebra crossing astute solution.
idea :
btTake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "btTake");};
if (inPreview) {
camera.setOneShotPreviewCallback(previewCallback);
inPreview=false;
}
}
});
The preview code :
final class PreviewCallback implements Camera.PreviewCallback {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i( tagLocal , "onPreviewFrame ");
File photo= new File(strFileName);
if (photo.exists()) {
photo.delete();
}
try {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
YuvImage image = new YuvImage(data, parameters.getPreviewFormat(),
size.width, size.height, null);
FileOutputStream filecon = new FileOutputStream(photo);
image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 90, filecon);
} catch (FileNotFoundException e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
/**
* Restart :
*/
File fileVerif = new File(strFileName);
if (fileVerif.exists() && fileVerif.length()!=0) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(tagLocal , "Photo stockée file lenght = "+ fileVerif.length());};
Intent intent = new Intent(CatchImageCommonsWare.this, Photo.class);
startActivity(intent);
finish();
} else {
new Exception("CatchImageCommonsWare", "PreviewCallback", "Pb stockage image = " + strFileName);
Toast.makeText(context, "Erreur enregistrement de la photo, essayez à nouveau", Toast.LENGTH_LONG).show();
}
}
}
I am making a camera app. I followed This tutorial to capture and save images in device. By implementing this, the image is captured and saved in device's gallery. It saves the image as file. But I want to get the bitmap of captured image. Here is my implementation,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_layout);
cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
filepath = Environment.getExternalStorageDirectory();
if (checkCameraHardware(this)) {
// Create an instance of Camera
mCamera = getCameraInstance();
try {
// Get Camera Parameters
Camera.Parameters params = mCamera.getParameters();
// Set the Focus Mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.setParameters(params);
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.cameraPreview);
preview.addView(mPreview);
} catch (Exception e) {
}
}
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
#Override
protected void onPause() {
// TODO OnPause Method
super.onPause();
releaseCamera();
}
// TODO Detecting Camera Hardware
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// This device has camera
return true;
} else {
// No Camera on this Device
return false;
}
}
// TODO Accessing Camera
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Takes the picture and write to file
File dir = new File(filepath.getAbsolutePath() + "/QR Codes/");
dir.mkdirs();
File pictureFile = getOutputMediaFile(FileColumns.MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d("PICFILE",
"Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
updateGallery();
} catch (Exception e) {
}
}
};
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
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;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
Convert your image from file to Bitmap. Like,
Bitmap bmp = BitmapFactory.decodeFile(urImageFilePath);
Try:
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data.length);
I Created a app that captures image and stores in the SD Card. The app seems to work fine with the previewing. But the problem is that when I run the app on my phone through eclipse the image gets captured. If I run my app in a normal way and try to capture the image, the image doesn't get captured.
I have attached my code below
My MainActivity.class
public class MainActivity extends Activity {
private ImageHandler preview;
Camera camera;
int cameraID, currentCamera;
Button capture;
FrameLayout imageLayout;
SurfaceView imgl;
private static final String TAG = "CallCamera";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* Invoking Camera and Setting the ImageHandler for preview
*/
camera = getCameraInstance();
preview = new ImageHandler(this, camera);
/*
* Getting the ID of the FrameLayout that displays the camera
*/
imageLayout = (FrameLayout) findViewById(R.id.preview_layout);
imageLayout.addView(preview);
/*
* Getting the ID of capture Button and setting its Functionality
*/
capture = (Button) findViewById(R.id.cameraButton);
capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(null, null, null, pic);
}
});
}
private Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera cam = null;
try {
cam = Camera.open();
} catch (Exception e) {
}
return cam;
}
PictureCallback pic = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
// File picFile = getOutputPhotoFile();
// if(picFile == null){
// return;
// }
//
// try{
// FileOutputStream fos = new FileOutputStream(picFile);
// fos.write(data);
// fos.close();
//
// }catch(FileNotFoundException e){
//
// }catch (IOException e){
//
// }
//
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Log.d(TAG, "Can't create directory to save image.");
Toast.makeText(getApplicationContext(),
"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 = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator
+ photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(getApplicationContext(),
"New Image saved:" + photoFile, Toast.LENGTH_LONG)
.show();
} catch (Exception error) {
Log.d(TAG,
"File" + filename + "not saved: " + error.getMessage());
Toast.makeText(getApplicationContext(),
"Image could not be saved.", Toast.LENGTH_LONG).show();
}
camera.startPreview();
}
private File getDir() {
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(sdDir, "CameraAPIDemo");
}
};
// private File getOutputPhotoFile() {
//
// File directory = new File(
// Environment
// .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
// "IMAGES_CAMERA");
//
// if (!directory.exists()) {
// if (!directory.mkdirs()) {
// Log.e(TAG, "Failed to create storage directory.");
// return null;
// }
// }
//
// String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss")
// .format(new Date());
//
// return new File(directory.getPath() + File.separator + "IMG_"
// + timeStamp + ".jpg");
// }
//
#Override
public void onResume() {
super.onResume();
if (camera == null) {
camera = Camera.open();
preview.setCamera(camera);
}
}
}
My Preview/ ImageHandler.class
public class ImageHandler extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private Camera imgCamera;
List<Size> imgSupportedPreviewSizes;
public ImageHandler(Context context, Camera camera) {
super(context);
// TODO Auto-generated constructor stub
this.imgCamera = camera;
this.holder = this.getHolder();
this.holder.addCallback(this);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
try {
imgCamera.setPreviewDisplay(holder);
imgCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
imgCamera.setPreviewDisplay(holder);
imgCamera.startPreview();
imgCamera.setDisplayOrientation(90);
} catch (Exception e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
imgCamera.stopPreview();
imgCamera.release();
}
public void setCamera(Camera camera) {
imgCamera = camera;
if (imgCamera != null) {
imgSupportedPreviewSizes = imgCamera.getParameters()
.getSupportedPreviewSizes();
requestLayout();
}
}
}
I want to be able to capture image when I run the app normally through my phone.
I am working on a custom Camera activity for my application.
I was following the instruction from the Android Developers site here:
http://developer.android.com/guide/topics/media/camera.html
Everything seems to works fine, except the Callback function is not called and the picture is not saved. Here is my code:
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private static final String TAG = "CameraActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "will now take picture");
mCamera.takePicture(null, null, mPicture);
Log.v(TAG, "will now release camera");
mCamera.release();
Log.v(TAG, "will now call finish()");
finish();
}
});
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.v(TAG, "Getting output media file");
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.v(TAG, "Error creating output file");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.v(TAG, e.getMessage());
} catch (IOException e) {
Log.v(TAG, e.getMessage());
}
}
};
private static File getOutputMediaFile() {
String state = Environment.getExternalStorageState();
if (!state.equals(Environment.MEDIA_MOUNTED)) {
return null;
}
else {
File folder_gui = new File(Environment.getExternalStorageDirectory() + File.separator + "GUI");
if (!folder_gui.exists()) {
Log.v(TAG, "Creating folder: " + folder_gui.getAbsolutePath());
folder_gui.mkdirs();
}
File outFile = new File(folder_gui, "temp.jpg");
Log.v(TAG, "Returnng file: " + outFile.getAbsolutePath());
return outFile;
}
}
After clicking the Button, I get logs: "will now take picture", "will now release camera" and "will now call finish". The activity finishes succesfully, but the Callback function was not called during the
mCamera.takePicture(null, null, mPicture);
function (There were no logs from the mPicture callback or getMediaOutputFile functions) and there is no file in the location that was specified.
Any ideas? :)
Much thanks!
The call to mCamera.takePicture() is asynchronous. That means that the call completes immediately, but the actual picture taking and processing happens sometime later. However, you do this immediately upon return from the call to mCamera.takePicture():
Log.v(TAG, "will now release camera");
mCamera.release();
Log.v(TAG, "will now call finish()");
finish();
That means that you have released the camera resources and finished the Activity before the camera gets a chance to actually take the picture and call you back.
You need to move that code into the callback method onPictureTaken() so that you release the resources and finish the Activity after the callback occurs.
Do it like this for taking multiple images on single Click Using SurfaceView Custom Camera
clickbtn.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
for (int i = 0; i < 5; i++) {
mcamera = mPreview.getCamera();
getimage(mcamera);
Toast.makeText(getApplicationContext(),
"multiple image count=" + i, 1000).show();
}
if (mPreview == null) {
mPreview = new CamLayer(MainActivity.this);
}
}
});
and
public static void getimage(Camera mcamera) {
PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
Log.e("path file 11111111", ""+pictureFile);
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (Exception e) {
}
}
};
try {
mcamera.startPreview();
mcamera.takePicture(null, null, mPicture);
Thread.sleep(2000);
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"Sunil3");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
File mediaFile = new File(String.format(mediaStorageDir+File.separator+"%d.jpg", System.currentTimeMillis()));
return mediaFile;
}