error while decoding image captured with camera - android

I am launching the camera to capture a picture, which is stored in a new file in a specific folder, in the external storage.
The problem is that when I try to decode the image from the file using BitmapFactory.decodeFile() in my onActivityResult() method, the returned image is null. Is this because the file is not yet complete (i.e. the process of the camera has not finished to save the image)? How can I solve this problem?
Here is the code with which I am launching the camera:
private void launchCamera() {
//create folder
File imagesFolder = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Consts.MEDIA_EXTERNAL_FOLDER);
if(!imagesFolder.exists())
imagesFolder.mkdirs();
String fileName = "pic_"+Consts.CAMERA_DATE_FORMAT.format(new Date());
File image = null;
try {
image = File.createTempFile(fileName, ".jpg", imagesFolder);
} catch(IOException e) {
Log.e(TAG, "Error creating new file.");
}
capturedImageURI = Uri.parse(image.getAbsolutePath());
//launch camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageURI);
startActivityForResult(intent, CAMERA_ACTION);
}
And this is when I get the image in the onActivityResult():
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CAMERA_ACTION:
getContentResolver().notifyChange(capturedImageURI, null);
File f = new File(capturedImageURI.toString());
decodedBitmap = Helper.decodeSampledBitmapFromResource(filePath);
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(decodedBitmap);
break;
}

How can I solve this problem?
File, AFAIK, does not understand file:/// URL formats, which is what you will get from capturedImageURI.toString(). Rather than regenerating the File, use the one you already created.

Related

Get bitmap from camera android

I'm trying to open the camera from my app and get a bitmap. But this doens't work. I got this error :
E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: content:/media/external/images/media/9969: open failed: ENOENT (No such file or directory)
Here is the code :
private void openCamera()
{
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.TITLE, "New Picture");
contentValues.put(MediaStore.Images.Media.DESCRIPTION, "From the camera");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
//Camera intent
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE);
}
When I call openCamera(), here is the activity result :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
switch (resultCode)
{
case RESULT_OK :
{
//imageView.setImageURI(image_uri); this works
Bitmap bitmap = null;
String photoPath = image_uri.toString();
bitmap = BitmapFactory.decodeFile(photoPath);
imageView.setImageBitmap(bitmap); //this doesnt work ! --> the bitmap is empty
}
//finish
case RESULT_CANCELED :
{
// finish();
}
default: {
//finish();
}
}
I need the bitmap to store the image after that.
It's pretty weird because the image is well saved into the gallery but I can't get it...
Ideally, you would be using Glide, Picasso, or another image-loading library, and simply have it load the image from the Uri into your ImageView.
If you insist upon using your basic approach, despite its poor performance, replace:
String photoPath = image_uri.toString();
bitmap = BitmapFactory.decodeFile(photoPath);
with:
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(image_uri));
A Uri is not a file.

How do I supply file path that is the same as the path in the gallery when taking photo in Android?

I tried to take a picture using camera intent and want to get the file path of the full size image. I am following the tutorial from http://developer.android.com/training/camera/photobasics.html. The problem, when I look into the file path in MediaStore.Images.Media.DATA column using MediaStore.Images.Media.EXTERNAL_CONTENT_URI, the image have different path. How do I supply the same file path? I looked at taking a photo and placing it in the Gallery, I though it is simply just change Environment.DIRECTORY_PICTURES to Environment.DIRECTORY_DCIM, but it still didn't work.
Below is my code for taking photo.
private Uri photoPath;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
getContentResolver().notifyChange(photoPath, null);
System.out.println(photoPath);
}
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.camera_button) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
try {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String image = "IMG_" + timestamp;
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File photo = File.createTempFile(image, ".jpg", storageDir);
photoPath = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoPath);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
my code above produce file path /storage/emulated/0/Pictures/IMG_20150805_121624.jpg while it is actually /storage/emulated/0/DCIM/100MEDIA/IMAG0531.jpg in the gallery. the former path is really my image (as I specified it on photoPath), but I want to get the later path instead. How could I do that?
You will have to use Environment.DIRECTORY_DCIM.
The android API DOC clearly has the details of various directories which can be used.
I hope this will help you to save your file to /storage/emulated/0/DCIM/.

IMAGE_CAPTURE on resultActivity the file doesn't exist yet

This a rare case, i'm trying to capture an image from native camera activity on my samsung galaxy s3 and onActivityResult the file doesn't exist to read yet. If i disconnect the phone and connect again then the i can see the image on my explorer.
It likes that the camera activity writes the file with delay or something...
i have readed all questions and answers and other forums, but it is my problem; My code:
... onCreate
File file = new File( _path );
pathUri = Uri.fromFile( file );
...
protected void startCameraActivity()
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, pathUri);
startActivityForResult( intent, CAMERA_REQUEST_CODE );
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK)
{
// test if exits image
if((new File(_path)).exists())
... do something
}
... continue
if((new File(_path)).exists()) always retunrs FALSE, how is it possible?
Thans in advance
I have never seen this occur in my app. However, this could potentially be a workaround.
Note: Declare the Uri instance initialURI globally so you can use it throughout the Activity. You could also change the name to something that suits your naming convention.
In this, right before the Intent is triggered, I pass a specific path for the Image to be stored at along with the name for the File.
Intent getCameraImage = new Intent("android.media.action.IMAGE_CAPTURE");
File cameraFolder;
if (android.os.Environment.getExternalStorageState().equals
(android.os.Environment.MEDIA_MOUNTED))
cameraFolder = new File(android.os.Environment.getExternalStorageDirectory(),
"SOME_FOLDER_NAME/");
else
cameraFolder= StatusUpdate.this.getCacheDir();
if(!cameraFolder.exists())
cameraFolder.mkdirs();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
String timeStamp = dateFormat.format(new Date());
String imageFileName = "picture_" + timeStamp + ".jpg";
File photo = new File(Environment.getExternalStorageDirectory(),
"SOME_FOLDER_NAME/" + imageFileName);
getCameraImage.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
initialURI = Uri.fromFile(photo);
startActivityForResult(getCameraImage, ACTION_REQUEST_CAMERA);
And finally, in the onActivityResult():
Note: This I'm guessing should work. My application uses the Aviary SDK and the code for that differs vastly from the conventional work done in this method.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK) {
// USE EITHER THIS
imgView.setImageURI(initialURI);
// OR USE THIS
getContentResolver().notifyChange(initialURI, null);
ContentResolver cr = getContentResolver();
try {
// SET THE IMAGE FROM THE CAMERA TO THE IMAGEVIEW
Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, initialURI);
// SET THE IMAGE USING THE BITMAP
imgvwSelectedImage.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
}
If you do not need the the Image stored on the SD-Card, you could delete it once you are done with it. This I am guessing (guessing because I have never experienced what the OP is facing problem with) this should do it for you.
Oh. Almost forgot. You will need to declare this permission in your Manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

How to put a date watermarker in android camera activity

I'm getting pictures with the next code:
public void foto(View v) {
nom_foto = Environment.getExternalStorageDirectory()+ aptr.ruta_temp + cuadrilla + "/" + medidor + "_"+ cont_foto + ".jpg";
File arch = new File(Environment.getExternalStorageDirectory()+ aptr.ruta_temp+ cuadrilla);
if (!arch.exists())
arch.mkdirs();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
int code = TAKE_PICTURE;
Uri output = Uri.fromFile(new File(nom_foto));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
startActivityForResult(intent, code);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE) {
ImageView iv = (ImageView) findViewById(R.id.minifoto);
if (resultCode == RESULT_OK) {
new MediaScannerConnectionClient() {
private MediaScannerConnection msc = null;
{
msc = new MediaScannerConnection(getApplicationContext(), this);
msc.connect();
}
public void onMediaScannerConnected() {msc.scanFile(nom_foto,null);
}
public void onScanCompleted(String path, Uri uri)
{ msc.disconnect();}};
Toast.makeText(usuario_lectura.this,"Foto N° " + cont_foto + " agregada correctamente", Toast.LENGTH_LONG).show();
cont_foto++;
iv.setVisibility(View.VISIBLE);
iv.setImageBitmap(BitmapFactory.decodeFile(nom_foto));
}
}
if (resultCode == RESULT_CANCELED) {
File file = new File(nom_foto);
if (file.exists())
file.delete();
}
}
}
Everything works properly, the picture has taken correctly and saved on the SD card... But, I have to add a watermarker, including the date... How can I add it?, the camera activity doesn't give me these option...
In order to add a textual or graphical watermark to your image from the camera, you must open the image, edit it in a Canvas with Paint/Graphics overlays, then re-encode it as a .jpg image, and re-save it as a file on the SD card. You can save over the original file from the camera. All of these steps are fairly straightforward.
There is, however, a serious hurdle.
Most devices will not be able to open the full-size image from the camera in a single Bitmap. There is not enough heap memory available. Therefore, you will have to use a scale factor inSampleSize to open your image. Thus, the watermarked image will be forever smaller by some factor than the original from the camera.
I do not think there is any way around this issue :(

Video Intent not saving video to desired location

I have implemented a code to save the captured video to a custom location.
// Constants
final static int REQUEST_VIDEO_CAPTURED = 1;
String CAPTURE_TITLE="MyVideo.3gp";
// Specified the desired location here
File file = new File(Environment.getExternalStorageDirectory() + "/DCIM", CAPTURE_TITLE);
Uri outputFileUri = Uri.fromFile( file );
Intent intent = new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, REQUEST_VIDEO_CAPTURED);
Now On Activity result I m getting the default path only and not the desired path where i intent to save the video.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
Uri capturedImageUri = data.getData();
Toast.makeText(this, capturedImageUri .getPath(), TOAST.LENGTH_LONG).show();
}
}
Now I dont know why it is not saving it to desired location similar thing I did try with Image capture and it worked.
Also I have added the desired permissions.
Any thoughts!!
try this instead...
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)), CAPTURE_TITLE);
File file = new File(Environment.getExternalStorageDirectory() + "/DCIM", CAPTURE_TITLE);
Change To:
File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", CAPTURE_TITLE);

Categories

Resources