Android Camera : Empty file in onActivityResult method - android

I have an activity to open camera intent and grab the photo in the onActivityResult method.
Three devices worked well without errors but only in one device I get null error on the file variable.
"Attempt to invoke virtual method java.lang.String java.io.File.getPath() on a null object reference"
This is the way how I implemented it.
A) Step one: Open camera
Upon clicking on a button I run the following code. This code will:
Create a new file
Open camera intent
//create file
imgName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".jpg";
//global variable
file = new File(Environment.getExternalStorageDirectory(), imgName);
if(file != null){
//save image here
Uri relativePath = Uri.fromFile(file);
//Open camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, relativePath);
startActivityForResult(intent, Constant.CAMERA_PIC_REQUEST);
}
B) Step two: Take a picture and click save button
C) Step three: Grab the picture in onActivityResult() method
Check the constant = Constant.CAMERA_PIC_REQUEST.
Get the EXIF data from the photo and find out the required angle to rotate the photo.
Set the width, height and angle. Create the .jpg photo
Save the created image name and path into imageArray
Set the grid view with imageArray
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case Constant.CAMERA_PIC_REQUEST:
try {
//Get EXIF data and rotate photo (1. file.getPath() has been used)
ExifInterface exif = new ExifInterface(file.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;// Landscape
//rotate photo
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix matrix = new Matrix();
matrix.postRotate(angle);
try {
//Create the rotated .jpg file (2. file.getPath() has been used)
Bitmap correctBmp = Func.decodeSampleBitmapFromFile(file.getPath(), Constant.PHOTO_WIDTH, Constant.PHOTO_HEIGHT);
correctBmp = Bitmap.createBitmap(correctBmp, 0, 0, correctBmp.getWidth(), correctBmp.getHeight(), matrix, true);
FileOutputStream fOut;
fOut = new FileOutputStream(file);
correctBmp.compress(Bitmap.CompressFormat.JPEG, 80, fOut);
fOut.flush();
fOut.close();
//image saved successfully - add photo name into reference array. Later I will use this
//(3. file.getPath() has been used)
Image img = new Image();
img.setImageName(imgName);
img.setAbsolutePath(file.getAbsolutePath());
img.setRelativePath(Uri.fromFile(file));
imageArray.add(img);//save in array
} catch (FileNotFoundException e) {
Log.e("Error", e.getMessage());
} catch (IOException e) {
Log.e("Error", e.getMessage());
}
} catch (Exception e) {
//This exception is triggering.
Log.e("Error 15", e.getMessage());
}
//set this photo in a grid view for user to see
setGridView(imageArray);
break;
case Constant.POPUPFRAG:
//something else
break;
default:
//deafult
break;
}
}
}
Error 15 (third exception) is triggering only in one phone. I'm not sure why is that. It shows the null pointer exception that I posted above.
Three devices that could run above code is having at least android v4.0 or above.
The phone that gives me null exception is Samsung Galaxy Note 3 Android v5.0. (Although the code is failing, I could find the photo in the phone gallery)
Can you please suggest me what could go wrong here? Am I missing something?
Anyway to improve this code?
Thanks!

Instead of directly using file.getPath() you can get use like this.
Create Global varibale of Uri then use it in all activity.
private Uri imageToUploadUri;
file = new File(Environment.getExternalStorageDirectory(), imgName);
if(file != null){
//save image here
imageToUploadUri = Uri.fromFile(file);
//Open camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageToUploadUri);
startActivityForResult(intent, Constant.CAMERA_PIC_REQUEST);
}
then in your onActivityResult() use like this:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case Constant.CAMERA_PIC_REQUEST:
try {
ExifInterface exif = new ExifInterface(imageToUploadUri.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;// Landscape
//rotate photo
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix matrix = new Matrix();
matrix.postRotate(angle);
try {
//Create the rotated .jpg file (2. file.getPath() has been used)
Bitmap correctBmp = Func.decodeSampleBitmapFromFile(imageToUploadUri.getPath(), Constant.PHOTO_WIDTH, Constant.PHOTO_HEIGHT);
correctBmp = Bitmap.createBitmap(correctBmp, 0, 0, correctBmp.getWidth(), correctBmp.getHeight(), matrix, true);
FileOutputStream fOut;
fOut = new FileOutputStream(file);
correctBmp.compress(Bitmap.CompressFormat.JPEG, 80, fOut);
fOut.flush();
fOut.close();
//image saved successfully - add photo name into reference array. Later I will use this
//(3. file.getPath() has been used)
Image img = new Image();
img.setImageName(imgName);
img.setAbsolutePath(file.getAbsolutePath());
img.setRelativePath(imageToUploadUri);
imageArray.add(img);//save in array
} catch (FileNotFoundException e) {
Log.e("Error", e.getMessage());
} catch (IOException e) {
Log.e("Error", e.getMessage());
}
} catch (Exception e) {
//This exception is triggering.
Log.e("Error 15", e.getMessage());
}
//set this photo in a grid view for user to see
setGridView(imageArray);
break;
case Constant.POPUPFRAG:
//something else
break;
default:
//deafult
break;
}
}
}
I hope it helps you!

Related

Camera picture from storage to imageview?

I have a code, where you can take a picture, and then save it like 1.jpg,2.jpg,3.jpg. The problem is that I have no idea how to display the taken image in my second activity.
Button capture = (Button) findViewById(R.id.btnCapture);
capture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Here, the counter will be incremented each time, and the
// picture taken by camera will be stored as 1.jpg,2.jpg
// and likewise.
count++;
String file = dir+count+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
}
catch (IOException e)
{
}
Uri outputFileUri = Uri.fromFile(newfile);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
Log.d("CameraDemo", "Pic saved");
}
}
}
If I try to pass my image as parcable, the quality is pretty bad, that's what I don't want. Anybody can help me with this, or show a good guide? The most important is that I don't want to display it in my first activity, I want to display it in my second activity, calling the path of the 1.jpg. Thanks!
The way is to write the picture taken to a file and get the path to said file and passing the path to the next activity and intializing a bitmap using said path to file and setting the image view...ill post a code soon
mean while look into here while i post a snippet
EDIT: SNIPPET
this code sets up camera to take a picture and save to a file.
private void onCameraSelected() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, PICTURE_CAMERA);
}
private Uri getOutputMediaFileUri() {
return Uri.fromFile(getOutputMediaFile());
}
private File getOutputMediaFile() {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
on the onActivityResult detect resultcode/request code for camera and consume it like so
private void loadImageFromCamera(Intent data) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
// downsizing image as it throws OutOfMemory Exception for larger images
// options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(), options);
setLoadedImage(bitmap);// set bitmap to imageview here.
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IOException e) {
Logger.logError("File not found :" + fileUri.getPath());
e.printStackTrace();
}
}
Basically youre playing with the variable String filePath = fileUri.getPath(); // just declare Uri fileUri in activity level or something.
You will need to pass the camera intent a location to save the image. You then have to retrieve the image from the phones storage in order to display it in an image view.
set a member variable to keep track of the image:
private Uri mImageUir;
Then to request a camera intent:
File photo = null;
try {
// place where to store camera taken picture
photo = createTemporaryFile("picture", ".jpg");
photo.delete();
} catch (Exception e) {
e.printStackTrace();
}
mImageUir = Uri.fromFile(photo);
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUir);
activity.startActivityForResult(intent, TAKE_PHOTO);
...
private File createTemporaryFile(String part, String ext) throws Exception
{
File tempDir= Environment.getExternalStorageDirectory();
tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
if(!tempDir.exists())
{
tempDir.mkdir();
}
return File.createTempFile(part, ext, tempDir);
}
Then in your OnActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == Activity.RESULT_OK) {
//firstly find correct orientation of photo
ExifInterface exif = null;
Integer photoOrientation = null;
try {
exif = new ExifInterface(mImageUir.getPath());
photoOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap photo;
ContentResolver resolver = getContext().getContentResolver();
try {
//get the image file
photo = MediaStore.Images.Media.getBitmap(resolver, mImageUir);
//You should scale it down here if you dont need in full size
//rotate to correct orientation
if(photoOrientation != null) {
photo = rotateBitmap(photo, photoOrientation);
}
mYourImageView.setImageBitmap(photo);
//delete temporary image file (if you need to)
}
catch (Exception e){
e.printStackTrace();
}
}
}
and here is my method to rotate the image:
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}

Taking picture with camera intent rotate picture in portrait mode android

Picture was taken successfully with camera but in portrait mode on samsung galaxy s3 the picture gets rotated. How can i solve this issue.
Camera intent is as follows:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(xdestination));
startActivityForResult(intent, CAMERA_PIC_REQUEST);
In activity for result
if (requestCode==CAMERA_PIC_REQUEST){
// Bitmap bm = (Bitmap) data.getExtras().get("data");
Uri photo_uri = Uri.fromFile(xdestination);
Editer.PHOTO_FROM=11;
Bitmap decodeSampledBitmapFromFile=null;
try {
decodeSampledBitmapFromFile = decodeUri(photo_uri);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
decodeSampledBitmapFromFile.compress(Bitmap.CompressFormat.JPEG,100, bytes);
File f = new File(Environment.getExternalStorageDirectory(), "user_image.jpg");
try {
if(f.exists())
f.delete();
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
} catch (IOException e) {
e.printStackTrace( );
Log.d("ERROR", e.toString());
}
}
Pass your taken picture and SDCard path of that picture into the following method which will return the correct oriented picture...
private Bitmap imageOreintationValidator(Bitmap bitmap, String path) {
ExifInterface ei;
try {
ei = new ExifInterface(path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
bitmap = rotateImage(bitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
bitmap = rotateImage(bitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
bitmap = rotateImage(bitmap, 270);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
private Bitmap rotateImage(Bitmap source, float angle) {
Bitmap bitmap = null;
Matrix matrix = new Matrix();
matrix.postRotate(angle);
try {
bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
} catch (OutOfMemoryError err) {
err.printStackTrace();
}
return bitmap;
}
Use :
public int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Log.i("RotateImage", "Exif orientation: " + orientation);
Log.i("RotateImage", "Rotate value: " + rotate);
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
Try it like below.
File photo = new File(Environment.getExternalStorageDirectory(), "user_image.jpg");
if (photo.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(photo
.getAbsolutePath());
imageView.setImageBitmap(myBitmap);
imageView.setRotation(90);
}
Step 1: Give a full path of your photo like File photo = new File(Environment.getExternalStorageDirectory()
, "Face.jpg");
Step 2: Check whether photo is exist or not if yes then set it to image view and rotate it to 90 degree.
You have no choice but read the image, rotate it and write the result back to SD card. The straightforward approach, using BitmapFactory, will easily run into OutOfMemory exception.
Alternatively, you can use JPEG lossless rotation, using jpegtran.
On SourceForge, there is a Java open source class LLJTran. The Android port is on GitHub.
Today I faced this problem. I know I'm late, but just in case someone needs it. In my case, if I pass the Uri inside the camera intent, then the output file was rotated. That is,
fun takePhoto() {
val intent = Intent(android.media.action.IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(xdestination)) // <-- this line is the culprit for me
startActivityForResult(intent, CAMERA_PIC_REQUEST)
}
Then inside onActivity result, you get the bitmap rotated. I don't know why that happened.
So I didnot provide the Uri to the intent. That is I wrote this:
fun takePhoto() {
val intent = Intent(android.media.action.IMAGE_CAPTURE)
startActivityForResult(intent, CAMERA_PIC_REQUEST)
}
Therefore, inside onActivityResult I got the returned image as bitmap. Then I manually saved that bitmap inside the desired file / Uri.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == PHOTO_CAPTURE_WITH_CAMERA_REQ_CODE && resultCode == RESULT_OK) {
// 1. handle the image as normal bitmap
val photo: Bitmap? = data?.extras?.get("data") as Bitmap;
// handleImage(SharedData.pendingPhotoUri.pop())
if (photo != null) {
// inside handle camera
handleCameraImage(photo)
};
}
}
private fun handleCameraImage(inputBitmap: Bitmap) {
//2. according to previous implementation, this uri should be the final output image file.
// 3. save the original bitmap in a temp image file
val tempBitmapFile: String = requireActivity().cacheDir.absolutePath +"/temp_photo_"+System.currentTimeMillis();
val fOuttemp: FileOutputStream = FileOutputStream(tempBitmapFile);
inputBitmap.compress(Bitmap.CompressFormat.PNG, 85, fOuttemp);
fOuttemp.flush();
fOuttemp.close();
// 4. use ExifInterface to make sure the photo is in right orientation.
val exifInterface: ExifInterface = ExifInterface(tempBitmapFile);
val orientation: Int = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Timber.tag(TAG).e("orientation == " + orientation);
var matrix = Matrix();
var isRotationNeeded: Boolean = true;
when(orientation){
ExifInterface.ORIENTATION_NORMAL -> {
Timber.tag(TAG).e("when ExifInterface.ORIENTATION_NORMAL");
// do nothing I guess
isRotationNeeded = false;
}
ExifInterface.ORIENTATION_ROTATE_90 -> {
Timber.tag(TAG).e("when ExifInterface.ORIENTATION_ROTATE_90");
matrix.setRotate(90f);
}
ExifInterface.ORIENTATION_ROTATE_180 -> {
Timber.tag(TAG).e("when ExifInterface.ORIENTATION_ROTATE_180");
matrix.setRotate(180f);
}
ExifInterface.ORIENTATION_ROTATE_270 -> {
Timber.tag(TAG).e("when ExifInterface.ORIENTATION_ROTATE_270");
matrix.setRotate(270f);
}
else -> {
Timber.tag(TAG).e("when else");
isRotationNeeded = false;
}
}
// if in wrong orientation,
// rotate image and save it in the file from step 2.
// else save the original image in the file from step 2.
lateinit var outputBitmap: Bitmap;
if(!isRotationNeeded) {
outputBitmap = inputBitmap;
}else{
outputBitmap = Bitmap.createBitmap(inputBitmap, 0, 0, inputBitmap.width,
inputBitmap.height, matrix, true);
}
val outputBitmapfile: File = File("your_awesome_file");
val fOut: FileOutputStream = FileOutputStream(outputBitmapfile);
outputBitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
var outputPhotoUri:Uri = getUriForFile(requireActivty(), outputBitmapfile);
// 5. finally use this photo / Uri to do whatever you want
}
fun getUriForFile(context: Context, file: File?): Uri? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N || Config.ONLY_INTERNAL_STORAGE) {
try {
val destCopiedTempFile = File(context.getExternalFilesDir(null).toString() + File.separator + "temp")
FileBackend.copy(file, destCopiedTempFile)
FileProvider.getUriForFile(context,
BuildConfig.APPLICATION_ID + ".fileprovider", destCopiedTempFile)
} catch (e: IllegalArgumentException) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
throw SecurityException(e)
} else {
Uri.fromFile(file)
}
}
} else {
Uri.fromFile(file)
}
}
This worked for me.

Saving picture to app directory returns null in onActivityResult

I am saving an image to the application directory by using the following with my intent (Got it from the android dev site):
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getApplicationContext().getFilesDir();
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
return image;
}
And then in the onClick:
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
Toast.makeText(getActivity().getApplicationContext(), "File not created", Toast.LENGTH_LONG).show();
}
if (photoFile != null){
Intent camIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
camIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
getActivity().startActivityForResult(camIntent, 0);
}
Up to here it works perfectly fine. I checked in the app dir using my file manager and the pictures get saved and they cannot be seen by other apps, as it should be. The problem is that when I try to display it in my ImageView I get a NullPointerException. This is the problem code:
private void setCameraPicture(int picture_count, Intent data) {
// TODO Auto-generated method stub
Bitmap bm = null;
try {
Uri selectedImage = data.getData();
Toast.makeText(getApplicationContext(), "picture = " + selectedImage, Toast.LENGTH_LONG).show();
String camPictureString = getRealPathFromURI(selectedImage);
File f = new File(camPictureString);
ExifInterface ei = new ExifInterface(camPictureString);
int rotation = 0;
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
rotation = 90;
bm = rotateCameraImage(rotation, f);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
rotation = 180;
bm = rotateCameraImage(rotation, f);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
rotation = 270;
bm = rotateCameraImage(rotation, f);
} else {
bm = rotateCameraImage(rotation, f);
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "IOException", Toast.LENGTH_LONG).show();
} catch (NullPointerException e) {
// TODO: handle exception
Toast.makeText(getApplicationContext(), "NullPointerException", Toast.LENGTH_LONG).show();
}
}
The line Uri selectedImage = data.getData(); returns null. Am I doing this wrong? I call the setCameraPicture() from my onActivityResult() and pass the Intent data in as a parameter.
This code works fine if I don't save to the application directory. Do any of you have any suggestions? Any help will be appreciated. Thank you in advance
getData() returns null because you've specified a custom file to save the Image in (Media.EXTRA_OUTPUT). The data is stored in the path that you've specified, and not returned in your onActivityResult(). This makes sense because there is no reason to return it if the data is already stored somewhere. Just simply retrieve the Bitmap image from the path.

android image capture always landscape and not full size

I want to add image capturing in my Android app where user can captures images, I'm using the following code:
public void open_camera() {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
try {
// place where to store camera taken picture
photo = this.createTemporaryFile("picture", ".jpg");
photo.delete();
} catch(Exception e) {
Toast.makeText(this, "Please check SD card! Image shot is impossible!", 10000);
}
mImageUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
//start camera intent
startActivityForResult(intent,SELECT_PICTURE_CAMERA );
//Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//startActivityForResult(cameraIntent, SELECT_PICTURE_CAMERA);
}
private File createTemporaryFile(String part, String ext) throws Exception {
File tempDir= Environment.getExternalStorageDirectory();
tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
if(!tempDir.exists()) {
tempDir.mkdir();
}
return File.createTempFile(part, ext, tempDir);
}
When I retrieve
case SELECT_PICTURE_CAMERA:
if(resultCode == RESULT_OK) {
// Toast.makeText(this,"Camera" + imageReturnedIntent.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_LONG).show();
//this.yourSelectedImage = (Bitmap) imageReturnedIntent.getExtras().get("data");
/*
ImageButton imgbtn = (ImageButton) findViewById(R.id.imageButton_Photo);
BitmapDrawable background = new BitmapDrawable(this.yourSelectedImage);
imgbtn.setBackgroundDrawable(background);
*/
try {
File f=new File(mImageUri.getPath());
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix mat = new Matrix();
mat.postRotate(90);
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, null);
this.yourSelectedImage = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
} catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
} catch(OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}
But unfortunately after doing all this, still image is not of full size and it's always landscape.
You have a small mistake in code, after you get the angle the image should rotate you need to use this value in postRotate.
Please replace the line:
mat.postRotate(90);
with:
mat.postRotate(angle);
Hope I helped you :-)
Regards,
Woody.

set orientation of android camera started with intent ACTION_IMAGE_CAPTURE [duplicate]

This question already has answers here:
Why does an image captured using camera intent gets rotated on some devices on Android?
(23 answers)
Closed 4 years ago.
I'm working at an application in android which uses camera to take photos.For starting the camera I'm using an intent ACTION_IMAGE_CAPTURE like this:
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File image=new File(Environment.getExternalStorageDirectory(),"PhotoContest.jpg");
camera.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(image));
imageUri=Uri.fromFile(image);
startActivityForResult(camera,1);
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case 1:
if (resultCode == Activity.RESULT_OK) {
selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
image= (ImageView) findViewById(R.id.imageview);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(cr, selectedImage);
image.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());
}
}
else
if(resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(EditPhoto.this, "Picture could not be taken.", Toast.LENGTH_SHORT).show();
}
}
}
The problem is that all the photos that are taken are rotated with 90 degrees-horizontally aligned.
I've also put this into my manifest file:
<activity android:name=".EditPhoto">
android:screenOrientation="portrait"
</activity>
But still with no result!So can anyone help me???
http://developer.android.com/reference/android/media/ExifInterface.html
http://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION
So if in
Activity.onActivityResult(data, request, result) {
if (request == PHOTO_REQUEST && result == RESULT_OK) {
...
Uri imageUri = ...
File imageFile = new File(imageUri.toString());
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate-=90;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate-=90;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate-=90;
}
Canvas canvas = new Canvas(bitmap);
canvas.rotate(rotate);
}
Does this help at all?
Just to add to Greg's great answer, here's a whole "category" to do the job:
public static int neededRotation(File ff)
{
try
{
ExifInterface exif = new ExifInterface(ff.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
{ return 270; }
if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
{ return 180; }
if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
{ return 90; }
return 0;
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return 0;
}
you'd use it more or less like this ...
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == REQUEST_IMAGE_CAPTURE) // && resultCode == RESULT_OK )
{
try
{
Bitmap cameraBmp = MediaStore.Images.Media.getBitmap(
State.mainActivity.getContentResolver(),
Uri.fromFile( Utils.tempFileForAnImage() ) );
cameraBmp = ThumbnailUtils.extractThumbnail(cameraBmp, 320,320);
// NOTE incredibly useful trick for cropping/resizing square
// http://stackoverflow.com/a/17733530/294884
Matrix m = new Matrix();
m.postRotate( Utils.neededRotation(Utils.tempFileForAnImage()) );
cameraBmp = Bitmap.createBitmap(cameraBmp,
0, 0, cameraBmp.getWidth(), cameraBmp.getHeight(),
m, true);
yourImageView.setImageBitmap(cameraBmp);
// to convert to bytes...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
cameraBmp.compress(Bitmap.CompressFormat.JPEG, 75, baos);
//or say cameraBmp.compress(Bitmap.CompressFormat.PNG, 0, baos);
imageBytesRESULT = baos.toByteArray();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return;
}
}
Hope it saves someone some typing in the future.
The above answer is very thorough, but I found I had to do a little bit more in order for every case to work, especially if you're dealing with images from other sources such as the Gallery or Google Photos. Here's my DetermineOrientation method. I have a utility class where this is located so I have to pass in the Activity in order to use managedQuery(which btw is deprecated so use cautiously). The reason I have to use two methods is because, depending on the source of the image, ExifInterface will not work. For instance, if I take a camera photo, Exif works fine. However, if I'm also choosing images from the Gallery or Google Drive, Exif does not work and always returns 0. Hope this helps someone.
public static int DetermineOrientation(Activity activity, Uri fileUri)
{
int orientation = -1;
int rotate = 0;
try {
ExifInterface exif = new ExifInterface(fileUri.getPath());
orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if(rotate == 0)
{
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = activity.managedQuery(fileUri, orientationColumn, null, null, null);
orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
if(orientation != -1)
{
rotate = orientation;
}
}
return rotate;
}

Categories

Resources