Reputation: 31
I have a couple of days trying to capture a photo in android, the idea is to upload the file to a FTP once captured the image. I have a class that extends SurfaceView, when it becomes visible, plays back the image of the rear camera of the device, up here all right. Clicking on the image of the camera, I would like to keep the image in JPEG format.
I've tried dozens of solutions but, what I get right now is a JPEG totally black. I think im in the right way, but something is missing.
Here is the code I use in onClick event on the custom class:
try {
//create bitmap screen capture
Bitmap bitmap;
this.setDrawingCacheEnabled(true);
//Freezes the image
mCamera.stopPreview();
bitmap = Bitmap.createBitmap(getDrawingCache(), 0, 0, this.getLayoutParams().width, this.getLayoutParams().height);
this.setDrawingCacheEnabled(false);
//Create temp file
file = File.createTempFile("prueba", ".JPG", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
//Copy bitmap content into file
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 60, fos);
fos.flush();
fos.close();
//Free camera
mCamera.release();
mCamera = null;
}catch(Exception e){
e.printStackTrace();
}
mCamera is android.hardware.Camera, with specific size selected and copied width and height to this.layoutParams to well fit, all this in surfaceCreated() method.
Hope somebody can help me with any indication.
Thank you very much.
Upvotes: 1
Views: 1650
Reputation: 31
thank you for the help.
I've finally taken your solution. I liked the first option, because the camera was integrated into the application and it was easier to control the rotation of the image and the resolution of the preview.
By now, the image taked in the intent is resized and loaded into the object ImagePreview (that is an ImageView). Here is my solution:
CALL THE CAMERA INTENT:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size()>0) {
pathImagen = android.net.Uri.fromFile(File.createTempFile("prueba"+System.currentTimeMillis(), ".JPG", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, pathImagen);
startActivityForResult(intent, 94010);
}
GET THE IMAGE FILE AND RESIZE:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 94010:
if (resultCode == Activity.RESULT_OK) {
Bitmap bmp = null;
try {
//Obtenemos las dimensiones de la imagen (no se carga la imagen completa)
ContentResolver cr = getContentResolver();
cr.notifyChange(pathImagen, null);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathImagen.getEncodedPath(), options);
//bmp = android.provider.MediaStore.Images.Media.getBitmap(cr, pathImagen);
System.out.println("Tamaño imagen: "+options.outWidth+"x"+options.outHeight);
//Bitmap bmp = (Bitmap) data.getExtras().get("data");
int anchoFinal = 480;
int altoFinal = (options.outHeight*480)/options.outWidth;
options.inJustDecodeBounds = false;
bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(pathImagen.getEncodedPath(), options), anchoFinal, altoFinal, false);
System.out.println("Tamaño imagen despues escalar: "+bmp.getWidth()+"x"+bmp.getHeight());
this.imagePreView.setVisibility(View.VISIBLE);
this.imagePreView.getLayoutParams().width = bmp.getWidth();
this.imagePreView.getLayoutParams().height = bmp.getHeight();
this.imagePreView.setImageBitmap(bmp);
this.popupEditObject.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The only problem is that the image always comes with a resolution of 3264x1968. No matter who has taken horizontally or vertically o_O I'll see if the Intent returns some information about that.
I hope this helps more people and I have seen many forums with no answers that really works.
I would appreciate any feedback to refine the code.
Thanks again!
Upvotes: 1
Reputation: 3452
I don't know if your bitmap has valid data or not but I can tell you the common way to do what you are asking is to either startActivityForResult to launch the camera and get back an image:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
or to attach a callback for the camera preview and you could process the image frames there http://developer.android.com/reference/android/hardware/Camera.html#setPreviewCallback(android.hardware.Camera.PreviewCallback)
If all you want is to allow the user to take a picture then I think launching the intent as I described above is the solution for you. Here's a working code snippet that I have in one of the apps I've written:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// we want the camera image to be put in a specific place
File path;
try {
path = new File(getCameraStoragePath());
} catch (Exception e1) {
e1.printStackTrace();
return;
}
SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS");
mFilename = mPeer + "." + timeStampFormat.format(new java.util.Date()) + ".jpg";
try
{
mPath = path.getCanonicalPath();
} catch (IOException e)
{
e.printStackTrace();
}
File out = new File(path, mFilename);
android.net.Uri uri = android.net.Uri.fromFile(out);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
activity.startActivityForResult(intent, CAMERA);
Then implement your own onActivityResult to deal with the image after it's taken by the user:
protected void onActivityResult(int requestCode, int resultCode, Intent data);
Upvotes: 0