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;
}
}
Related
I want to save the image without compressing it and want to save it in it's original form i.e. when image is compressed the image size decreases and image become small. I am using native camera for this purpose. I am working in android studio. I am making an app in which i am using a camera to save image. But the image is compressed and is very small and very lower quality.
Below is my code for saving image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
{
if(resultCode == Activity.RESULT_OK)
{
Bitmap bmp = (Bitmap)data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
// convert byte array to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
if(isStoragePermissionGranted())
{
SaveImage(bitmap);
}
}
}else {
switch (requestCode) {
case 1000:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
getLocation();
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
Toast.makeText(this, "Location Service not Enabled", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
}
private void SaveImage(Bitmap finalBitmap) {
File storageDir = new File (String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)));
String root = storageDir + Environment.getExternalStorageDirectory().getAbsolutePath().toString();
Log.v(LOG_TAG, root);
File myDir = new File(root + "/captured_images");
if (!myDir .exists())
{
myDir .mkdirs();
}
Random generator = new Random();
int n = 1000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir,fname);
try {
file.createNewFile();
MediaScannerConnection.scanFile(getApplicationContext(), new String[] {file.getPath()} , new String[]{"image/*"}, null);
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Update 1
For more understanding i am putting my onClick method
btn_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Check permission for camera
if(ActivityCompat.checkSelfPermission(MainActivity.this, CAMERA)
!= PackageManager.PERMISSION_GRANTED)
{
// Check Permissions Now
// Callback onRequestPermissionsResult interceptado na Activity MainActivity
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{CAMERA},
MainActivity.REQUEST_CAMERA);
}
else {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE );
}
}
});
I searched the solution and found that i can use AndroidBitmapUtil
class so i copy and pasted this class into my project i.e. i created a new class. But i don't know how to use it. Although it is described that i can save image by doing new AndroidBmpUtil().save(bmImage, file);. But again i can't match with my code :(
Any help would be highly appreciated
new AndroidBmpUtil().save(source, sdcardBmpPath);
USER ABOVE LINE OF CODE AND FOLLOW BELOW LINK
https://github.com/ultrakain/AndroidBitmapUtil
Open Camera and save image into some specific directory.
solution number 1
private String pictureImagePath = "";
private void openBackCamera() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + ".jpg";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName;
File file = new File(pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, 1);}
Handle Image
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
File imgFile = new File(pictureImagePath);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
myImage.setImageBitmap(myBitmap);
}
}
solution number 2
I have used the following code and this works perfectly fine for me.
values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PICTURE_RESULT);
and also
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICTURE_RESULT:
if (requestCode == PICTURE_RESULT)
if (resultCode == Activity.RESULT_OK) {
try {
thumbnail = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
imgView.setImageBitmap(thumbnail);
imageurl = getRealPathFromURI(imageUri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
and
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
For opening camera use
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "imagename.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);
and in your onActivityresult method use
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("imagename.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),bitmapOptions);
yourimageview.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
I have some android code which taking photo from camera. But it is taking the picture as thumbnail but I want to take the picture as it is the original size. Here is my code:
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
CommonResources.photoFinishBitmap = thumbnail;
goForEditing();
//ivImage.setImageBitmap(thumbnail);
}
Can you help me how to get the original image instead of the thumbnail.
You will need to provide a file name for the full-sized photo to be saved into. You will also need to get access to file storage if you are running on Android 6.0 or later.
This answer should provide a code example of saving the full-sized image to a file: https://stackoverflow.com/a/20353771/5527154
Here is the documentation from Google: https://developer.android.com/training/camera/photobasics.html#TaskPath
To take a photo, first we need to declare required permissions in AndroidManifest.xml. We need two permissions:
Camera - to open camera app. If attribute required is set to true you will not be able to install this app if you don't have hardware camera.
WRITE_EXTERNAL_STORAGE - This permission is required to create new file, in which captured photo will be saved.
AndroidManifest.xml
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
The main idea in taking full-sized photo from camera is that we need to create new file for photo, before we open camera app and capture photo.
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.e("DEBUG_TAG", "createFile", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getAlbumDir();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStorageDirectory()
+ "/dcim/"
+ "MyRecipes");
if (!storageDir.mkdirs()) {
if (!storageDir.exists()) {
Log.d("CameraSample", "failed to create directory");
return null;
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
private void setPic() {
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the ImageView */
int targetW = recipeImage.getWidth();
int targetH = recipeImage.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 2;
if ((targetW > 0) && (targetH > 0)) {
scaleFactor = Math.max(photoW / targetW, photoH / targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Matrix matrix = new Matrix();
matrix.postRotate(getRotation());
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
/* Associate the Bitmap to the ImageView */
recipeImage.setImageBitmap(bitmap);
}
private float getRotation() {
try {
ExifInterface ei = new ExifInterface(mCurrentPhotoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return 90f;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180f;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270f;
default:
return 0f;
}
} catch (Exception e) {
Log.e("Add Recipe", "getRotation", e);
return 0f;
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
private void handleBigCameraPhoto() {
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
handleBigCameraPhoto();
}
}
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!
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.
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.