How do I properly compress an image and get the URI? - java

I'm trying to put the URIs of both the image and the thumbnail from a camera intent into a SQLite database.
I have the full image inserting just fine. I thought I had the thumbnail going in too but it's actually still the full image going into the database again.
Can I get a bit of guidance on how to go about doing this? I've tried a number of things so far but have been stuck for a couple days on this step.
Here are my relevant methods:
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;
File photoThumbnailFile = null;
try {
photoFile = createImageFile();
photoThumbnailFile = createImageThumbnailFile();
} catch (IOException ex) {
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this,
"com.example.jeremy.sqlwine.fileprovider",
photoFile);
photoThumbnailURI = FileProvider.getUriForFile(this,
"com.example.jeremy.sqlwine.fileprovider",
photoThumbnailFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
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 createImageThumbnailFile() throws IOException {
// Create an image thumbnail file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageThumbnailFileName = "THUMBNAIL_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageThumbnailFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoThumbnailPath = image.getAbsolutePath();
return image;
}
//This method will happen when the camera is done taking the picture
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Toast.makeText(this, "Image saved", Toast.LENGTH_SHORT).show();
bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), photoURI);
} catch (IOException e) {
e.printStackTrace();
}
bitmapThumbnail = ThumbnailUtils.extractThumbnail(bitmap,50,50);
imageThumbnail.setImageBitmap(bitmapThumbnail);
}
}

Related

Can't set imageview from Uri

In the MainActivity I take a picture from camera as the official documentation show:
private void dispatchTakePictureIntent() {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CAMERA);
} else {
if (Build.VERSION.SDK_INT >= 24) {
try {
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}
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) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, 2);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
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;
}
Then I save the photo to the gallery:
private Uri galleryAddPic() {
try{
file = new File(mCurrentPhotoPath);
MediaStore.Images.Media.insertImage(getContentResolver(),
file.getAbsolutePath(), file.getName(), null);
this.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Log.v("UriTaken", Uri.fromFile(file).toString());
return Uri.fromFile(file);
}
Then, with putExtra, I pass to the next activity the Uri of the file.
The uri is this:
file:///storage/emulated/0/Android/data/com.my.name.myappname/files/Pictures/JPEG_20181231_002549_9133887087473873179.jpg
In the new activity, I retrieve the uri, and before I set the imageview with it(if I use image.setImageURI(imageUri); it works), I want to rotate the image to the exact orientation(I don't know why in the image view is always rotated).
I use this code:
if (getIntent().getExtras() != null) {
imageUri = Uri.parse(getIntent().getStringExtra("uri"));
path = getPath(imageUri);
try {
//filePath = getFileName(path);
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Bitmap bitmap = BitmapFactory.decodeFile(path);
Bitmap rotatedBitmap = null;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotatedBitmap = rotateImage(bitmap, 90);
image.setImageBitmap(rotatedBitmap);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotatedBitmap = rotateImage(bitmap, 180);
image.setImageBitmap(rotatedBitmap);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotatedBitmap = rotateImage(bitmap, 270);
image.setImageBitmap(rotatedBitmap);
break;
case ExifInterface.ORIENTATION_NORMAL:
image.setImageBitmap(bitmap);
default:
rotatedBitmap = bitmap;
image.setImageBitmap(rotatedBitmap);
}
} catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
}
And here the method that cause the crash:
public String getPath(Uri imageUri) {
String wholeId = DocumentsContract.getDocumentId(imageUri);
String id = wholeId.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
On the first line of the method I got the error posted above, invalid uri: file///storage........etc
If I get the picture from gallery it works, because i get this Uri:
content://com.android.providers.media.documents/document/image%3A97897
I don't know if the problem is in the method that saves the image in the MainActivity or is in the getPath() method. What I need to do is to take a picture, save to the gallery and retrieve in the next activity.

app crashing after taking a pic on samsung phones only

I am developing an Android app in which the user can select a picture from the gallery or can click a photo through the phone's camera and save in the app's folder called FiZZ. The camera part of app runs perfectly fine on all android phones except Samsung.The code given below throws a NullPointerException at image.setPath(fileUri.getPath()); and crashes.
MainActivity.java:
Below is how I take a photo and save it in /DCIM/FiZZ folder:
/**
* take a photo
*/
private void activeTakePhoto() {
final Dialog dialog = new Dialog(MainActivity.this);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
int MEDIA_TYPE_IMAGE = 1;
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
try {
FileOutputStream outputStream_image = openFileOutput(file_image, MODE_WORLD_READABLE);
outputStream_image.write(string.getBytes());
outputStream_image.close();
Toast.makeText(getBaseContext(), "location of image saved", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private Uri getOutputMediaFileUri(int MEDIA_TYPE_IMAGE) {
// TODO Auto-generated method stub
if(isExternalStorageWritable()) {
//Toast.makeText(getBaseContext(), "value: "+ Uri.fromFile(getOutputMediaFile(MEDIA_TYPE_IMAGE)), Toast.LENGTH_LONG).show();
return Uri.fromFile(getOutputMediaFile(MEDIA_TYPE_IMAGE));
}
else
return null;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
private File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "FiZZ");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("FiZZ", "failed to create directory");
Toast.makeText(getBaseContext(),"File directory creation failed",Toast.LENGTH_LONG).show();
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
int MEDIA_TYPE_IMAGE = 1;
if (type == MEDIA_TYPE_IMAGE){
//String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fname= "IMG_"+ timeStamp + ".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
The request_image_capture case is called:
case REQUEST_IMAGE_CAPTURE:
if (requestCode == REQUEST_IMAGE_CAPTURE &&
resultCode == RESULT_OK) {
String filePath = imageFile.getAbsolutePath();
String imageName = String.valueOf(mediaFile);
Cursor cursor =
getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID},
MediaStore.Images.Media.DATA + "=? ",
new String[]{filePath}, null);
if (cursor != null && cursor.moveToFirst()) {
int column_index_data = cursor.getColumnIndexOrThrow(
MediaStore.MediaColumns._ID);
String picturePath = cursor.getString(column_index_data);
MyImage image = new MyImage();
image.setTitle(imageName);
image.setDescription(" ");
image.setDatetime(System.currentTimeMillis());
image.setPath(picturePath);
image.setName(null);
image.setPriority("OFF");
images.add(image);
daOdb.addImage(image);
adapter.notifyDataSetChanged();
cursor.close();
} else {
MyImage image = new MyImage();
image.setTitle(imageName);
image.setDescription(" ");
image.setDatetime(System.currentTimeMillis());
image.setPath(fileUri.getPath());//NullPointerException
image.setName(null);
image.setPriority("OFF");
images.add(image);
daOdb.addImage(image);
adapter.notifyDataSetChanged();
//swipelist.invalidateViews();
}
}

Saving Picture into Gallery from app

I have only began to code in java and am making an android application that takes a photo and saves the image to my gallery folder. My app takes the photo but for one reason or another it won't save the image.
static final int REQUEST_IMAGE_CAPTURE = 1;
public void onClickbtnCamera(View v){
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date(0));
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "/storage/emulated/0/DCIM/Camera/:" + image.getAbsolutePath();
return image;
}
static final int REQUEST_TAKE_PHOTO = 1;
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) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
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);
this.sendBroadcast(mediaScanIntent);
}

BitmapFactory open failed: ENOENT (No such file or directory)

I am trying to Take a Photo with Android Camera Intent as shown in this Tutorial: http://developer.android.com/training/camera/photobasics.html#TaskScalePhoto
The Photo is perfectly taken and is also safed at the given path. But anyway i'm getting following Error:
06-25 14:46:02.228 9070-9070/de.ema.flo.grapp E/BitmapFactory﹕
Unable to decode stream: java.io.FileNotFoundException:
file:/storage/emulated/0/Android/data/de.ema.flo.grapp/files/Pictures/IMG_20150625_144559002.JPG:
open failed: ENOENT (No such file or directory)
Create Image:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmssSSS").format(new Date());
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = new File(storageDir, "IMG_" + timeStamp + ".JPG");
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
Following code is called after taking the Photo in the Intent
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ACTION_TAKE_PHOTO_B && resultCode == Activity.RESULT_OK) {
if (mCurrentPhotoPath != null) {
ImageView mImageView = (ImageView) getActivity().findViewById(R.id.grillplatz_erstellen_image);
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
// Associate the Bitmap to the ImageView
mImageView.setImageBitmap(bitmap);
mCurrentPhotoPath = null;
}
}
}
I also tried it with this instead. But the result was the same: FileNotFoundException...
try {
InputStream is = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(is);
} catch (FileNotFoundException e) {
e.printStacktrace();
}
Are there any problems with this code? What could I try to change?
Please check the updated code.
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmssSSS").format(new Date());
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if(!storageDir.isexist)
storageDir.mkdirs();
File image = new File(storageDir, "IMG_" + timeStamp + ".JPG");
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
Let me know if it will help you or not.

How to save capture image with EXIF

i'm trying to capture image with android native camera, the save image is good but doesnt contain the usual EXIF data (gps tags, orientation...)
what do i need to do to save also the EXIF?
#Override
public void onClick(View v) {
Intent takePictureIntent = new Intent(android.provider.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) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));
imageuri = Uri.fromFile(photoFile);
startActivityForResult(takePictureIntent, CAMERA_PIC_REQUEST);
}
}
/*Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);*/
}
}
#SuppressLint("SimpleDateFormat")
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
Following is the method to Save an Image with EXIF Data (Location Data) to Gallery:
private String saveToGallery (Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to Directory
String photoDir = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DCIM + "/";
File directory = new File(photoDir);
// Creates image file with the name "newimage.jpg"
File myfilepath = new File(directory, "newimage.jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myfilepath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitgallery.compress(Bitmap.CompressFormat.JPEG, 80, fos);
fos.flush();
fos.close();
myfilepath.setReadable(true, false);
} catch (Exception e) {
e.printStackTrace();
}
Uri bitmapUri = Uri.fromFile(myfilepath);
String currentImageFile = bitmapUri.getPath();
//Writes Exif Information to the Image
try {
ExifInterfaceEx exif = new ExifInterfaceEx(currentImageFile);
Log.w("Location", String.valueOf(targetLocation));
exif.setLocation(targetLocation);
exif.saveAttributes();
} catch (Exception e) {
e.printStackTrace();
}
// Updating Gallery with the Image (Sending Broadcast to Gallery)
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentImageFile);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
return directory.getAbsolutePath();
}
The new image is not parsed, as it should be, by the MediaScanner. This smells like a device-specific bug.
See Image, saved to sdcard, doesn't appear in Android's Gallery app for workarounds.
Here is the function to save the Image,
public static String saveImageInExternalCacheDir(Context context, Bitmap bitmap, String myfileName) {
String fileName = myfileName.replace(' ', '_') + getCurrentDate().toString().replace(' ', '_').replace(":", "_");
String filePath = (context.getExternalCacheDir()).toString() + "/" + fileName + ".jpg";
try {
FileOutputStream fos = new FileOutputStream(new File(filePath));
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}

Categories