can i get image file width and height from uri in android? - android

i can getting the image width through MediaStore.Images.Media normally
but i need to getting the image width and height from image which selected from dropbox
so currently i have following method to getting image size from dropbox
private void getDropboxIMGSize(Uri uri){
String size = Long.toString(new File(uri.getPath()).length());
return size;
}
but what i actually need are getting the file width and height value
anyone know how to achieve that?please help!

private void getDropboxIMGSize(Uri uri){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(uri.getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
}
no there is no way. You have to create a Bitmap object. if you use the inJustDecodeBounds flag the bitmap would not be loaded in memory. In fact BitmapFactory.decodeFile will return null. In my example uri is the phisical path to the image

Blackbelt's answer is correct if you have a file uri. However, if you are using the new file providers as in the official camera tutorial, it won't work. This works for that case:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(
getContext().getContentResolver().openInputStream(mPhotoUri),
null,
options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;

Blackbelt's answer will work most of the time using Options, but I would like to propose another solution or fallback solution by using the ExifInterface. If you have the image URI, you can create the ExifInterface using the full path, no need for Bitmap object nor BitmapFactory.Options.
ex.
int width = exif.getAttributeInt( ExifInterface.TAG_IMAGE_WIDTH, defaultValue );
int height = exif.getAttributeInt( ExifInterface.TAG_IMAGE_LENGTH, defaultValue );

the solution is use new File(uri.getPath()).getAbsolutePath() instead of uri.toString()

The accepted answer returns with me a 0 of width/height, by replacing uri.getPath() with uri.getLastPathSegment(), it returns the correct dimensions
public static int[] getImageDimension(Uri uri){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(uri.getLastPathSegment()).getAbsolutePath(), options);
return new int[]{options.outWidth, options.outHeight};
}

In addition to #Blackbelt answer you should use the following code to retrieve file path from Uri:
public static String getPathFromURI(Context context, Uri contentUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
DocumentsContract.isDocumentUri(context, contentUri)) {
return getPathForV19AndUp(context, contentUri);
} else {
return getPathForPreV19(context, contentUri);
}
}
private static String getPathForPreV19(Context context, Uri contentUri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
try {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
} finally {
cursor.close();
}
}
return null;
}
#TargetApi(Build.VERSION_CODES.KITKAT)
private static String getPathForV19AndUp(Context context, Uri contentUri) {
String documentId = DocumentsContract.getDocumentId(contentUri);
String id = documentId.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
return cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}
return null;
}

For folks having content uri (starting with content://), open an InputStream & decode that stream to avoid getting 0 width and height. I'll use Kotlin
val uri: Uri = ....
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
val inputStream = contentResolver.openInputStream(uri)
BitmapFactory.decodeStream(inputStream, null, options)
val width = options.outWidth
val height = options.outHeight

Please use InputStream:
public int[] getImageSize(Uri uri){
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream input = this.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(input, null, options); input.close();
return new int[]{options.outWidth, options.outHeight};
}
catch (Exception e){}
return new int[]{0,0};
}
It'll return in array form:
int[]{ width , height }

This is a concrete working example of the ExifInterface solution proposed by #simplatek, using an extension function on the Uri type:
fun Uri.getImageDimensions(context: Context): Pair<Int, Int> {
val inputStream = context.contentResolver.openInputStream(this)!!
val exif = ExifInterface(inputStream)
val width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, defaultValue)
val height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, defaultValue)
return Pair(width, height)
}

If you guys keep getting (0,0) in the width and height, you probably want to decode a stream, and not a file.
It probably because you're trying to read an image from the assets. Try this:
val b = BitmapFactory.decodeStream(context.assets.open("path/in/assets/img.png"))
val width = b.width
val height = b.height

Related

MediaStore.Images get full image from thumb Uri /id

There are a couple of solutions on how to get thumbnail from the full image, such as
android get thumbnail of image stored on sdcard whose path is known
However, I need on the contrary to receive full image Uri from a Thumbnail Uri (or thumbnail id).
Here is how I get thumbnails:
fun getGalleryImages(): List<LocalImage> {
val baseUri: Uri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI
val listOfAllImages = ArrayList<LocalImage>()
// Set up an array of the Thumbnail Image ID column we want
val projection = arrayOf(MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.IMAGE_ID)
// Create the cursor pointing to the SDCard
val cursor = context.contentResolver.query(
baseUri,
projection,
null,
null,
null)
// Get the column index of the Thumbnails Image ID
val thumbColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID)
val fullColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID)
var thumbnailUri: Uri?
while (cursor.moveToNext()) {
val thumbId = cursor.getString(thumbColumnIndex)
thumbnailUri = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + thumbId)
// here I save image id for later retrieving full image
val imageId = cursor.getString(fullColumnIndex)
listOfAllImages.add(LocalImage(thumbnailUri = thumbnailUri), imId = imageId)
}
cursor.close()
return listOfAllImages
}
And then I have to retrieve a full image by image id (or by thumbnail Uri)
private fun getFullImage(imageId: String): Uri {
val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA)
val cursor = context.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
MediaStore.Images.Media._ID + "=?",
arrayOf(imageId),
null)
val columnIndex = cursor.getColumnIndex(projection[0])
if (cursor.moveToFirst()) {
return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + cursor.getString(1))
}
cursor.close()
return Uri.EMPTY
}
This returns me a Uri which looks realistic:
content://media/external/images/media//storage/emulated/0/DCIM/Camera/IMG_20170720_085045.jpg
However, the Uri seems to be invalid since I cannot retrieve the image from it:
val bitmap = MediaStore.Images.Media.getBitmap(activity.contentResolver, image.imageUri)
java.lang.IllegalStateException: Unknown URL: content://media/external/images/media//storage/emulated/0/DCIM/Camera/IMG_20170720_085045.jpg
at android.os.Parcel.readException(Parcel.java:1950)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:698)
Picasso also fails to load image from this Uri
add this code after you get Uri of image.
if (largeImagePath != null) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = OG;
thumbnail = BitmapFactory.decodeFile((largeImagePath), opts);
System.gc();
if (thumbnail != null) {
try {
thumbnail = Common.rotateImageIfRequired(mContext, thumbnail, Uri.fromFile(new File(largeImagePath)));
} catch (IOException e) {
e.printStackTrace();
}
imageCam(thumbnail);
}
}
public void imageCam(Bitmap thumbnail) {
Bitmap photo = thumbnail;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte b[] = bos.toByteArray();
encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
ll_preview.setVisibility(View.VISIBLE);
img_preview.setVisibility(View.VISIBLE);
img_preview.setImageBitmap(photo);
}
in Common.java file add this method in it.
/**
* Rotate an image if required.
*
* #param img The image bitmap
* #param selectedImage Image URI
* #return The resulted Bitmap after manipulation
*/
public static Bitmap rotateImageIfRequired(Context mContext, Bitmap img, Uri selectedImage) throws IOException {
InputStream input = mContext.getContentResolver().openInputStream(selectedImage);
ExifInterface ei;
if (Build.VERSION.SDK_INT > 23)
ei = new ExifInterface(input);
else
ei = new ExifInterface(selectedImage.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(img, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(img, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(img, 270);
default:
return img;
}
}
I think this will solve your problem

how to handle activity when returning null post launch of the camera application from the fragment

In a fragment,I am having the view pager(using fragmentPageAdapter) and recycler views to display the images.I have option to take the pictures and add to both of them(viewpager and recycler),
During oncreateView of the fragment,adapter has been created with predefined set of images,when i try to access the photos from album location i am trying to use getActivity.getContentResolver() to get Photos,But getActivity() itself returns null post the launch of the photoapplication,i think the problem happens with detach & attach of the fragment,How to handle this scenarios?
OncreateView of fragment
This Fragments extends basefragment which contains camera launch and Saves it in PhotoGallery
LinearLayoutManager layoutManager
= new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerView = (RecyclerView)v. findViewById(R.id.recycler_view);
adapter = new MyRecyclerAdapter(getActivity(),mJobSiteAlbum,getGalleryThumbnailViewCallBackListener);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(adapter);
Within Adapter
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
MyObject photoObject = MyObjects.get(i);
if(photoObject.getresId() == MyObject.LOCAL_IMAGE){
Bitmap bitmap = mBaseFragment.getImageFromGallery(photoObject.getSelectedUri());//trying to retrive image from Gallery
if(bitmap!=null){
Log.v("Bitmap>>>Wid",""+bitmap.getWidth());
Log.v("Bitmap>>>Ht",""+bitmap.getHeight());
}
customViewHolder.imageView.setImageBitmap(bitmap);
customViewHolder.imageView.getLayoutParams().height = 100;
customViewHolder.imageView.getLayoutParams().width = 100;
customViewHolder.imageView.requestLayout();
}else if(photoObject.getresId() == MyObject.WEB_IMAGE){
customViewHolder.imageView.setImageUrl(photoObject.getthumbnailimageUrl(), loader);
}
customViewHolder.imageView.setOnClickListener(clickListener);
customViewHolder.imageView.setTag(customViewHolder);
}
//This Method is frm basefragment
public Bitmap getImageFromGallery(Uri selectedImageUri){
Bitmap defaultImageBitmap = null;
try {
Log.v("URI VAL",
"selectedImageUri = " + selectedImageUri.toString());
String mselectedImagePath = getPath(selectedImageUri);
Log.v("URI VAL",
"mselectedImagePath = " + mselectedImagePath);
if (mselectedImagePath != null) {
System.out.println("local image");
String[] projection = {MediaStore.MediaColumns.DATA};
CursorLoader cursorLoader = new CursorLoader(getOurActivity(),
selectedImageUri, projection, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
String selectedImagePath;
if (cursor == null) {
selectedImagePath = selectedImageUri.getPath();
} else {
cursor.moveToFirst();
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
selectedImagePath = cursor.getString(column_index);
cursor.close();
}
Bitmap bm;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedImagePath, options);
final int REQUIRED_SIZE = 200;
int scale = 1;
while (options.outWidth / scale / 2 >= REQUIRED_SIZE
&& options.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
defaultImageBitmap = BitmapFactory.decodeFile(selectedImagePath, options);
} else {
System.out.println("picasa image!");
defaultImageBitmap = loadPicasaImageFromGallery(selectedImageUri);
}
}catch (Exception e){
System.out.println("Exception URI!"+e.getMessage());
defaultImageBitmap = getImageFromURI(selectedImageUri);
}
return defaultImageBitmap ;
public String getPath(Uri uri) {
String[] projection = { MediaStore.MediaColumns.DATA };
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);//This GetActivity returns null post launch of the gallery application
//Do Something to get Path from Cursor
}
}
}

How to get image from video file

Hi i'm developer in korea. I have some question so i enter this site.
InputStream is;
URL url =
new URL("http://112.216.25.58:8888/VOD_LAUNCHER/media/youtube_sample3.mp4");
Uri uri = Uri.parse(url.toURI().toString());
is = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
//Bitmap bitmap = BitmapFactory.decodeFile(url.toString());
//MediaMetadataRetriever ret = new MediaMetadataRetriever();
//ret.setDataSource(url.toString());
//Bitmap bitmap = ret.getFrameAtTime(0);
//mImageView.setImageURI(uri);
//Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(uri.toString(), Thumbnails.MICRO_KIND);
mImageView.setImageBitmap(bitmap);
private Bitmap getPreview(URI uri) {
File image = new File(uri);
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image.getPath(), bounds);
if ((bounds.outWidth == -1) || (bounds.outHeight == -1))
return null;
int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
: bounds.outWidth;
BitmapFactory.Options opts = new BitmapFactory.Options();
//opts.inSampleSize = originalSize / THUMBNAIL_SIZE;
return BitmapFactory.decodeFile(image.getPath(), opts);
}
private String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getApplicationContext(),
contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I try to use ThumbnailUtil and etc but it didn't work.
How to get ThumbnailImage on android 4.0?
Thanks any reply.
From API level 8 you can just do this:
String path = /*get video path*/;
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
MediaStore.Images.Thumbnails.MINI_KIND);
Nice and simple :)
If you want to extract a frame of a video you should use this class. The code should be something like that:
MediaMetadataRetriever media = new MediaMetadataRetriever();
media.setDataSource(path);
Bitmap extractedImage = media.getFrameAtTime(time, option);
Hope it´s useful
Try This to get Thumbnail of a Video.
ImageView videoview;
Bitmap thumb = ThumbnailUtils.createVideoThumbnail("YOUR VIDEO STRING PATH", MediaStore.Images.Thumbnails.MINI_KIND);
Matrix matrix = new Matrix();
Bitmap bmThumbnail = Bitmap.createBitmap(thumb, 0, 0,
thumb.getWidth(), thumb.getHeight(), matrix, true);
videoview.setImageBitmap(bmThumbnail);
Edited: Use this method to get string path of Video URI.
/**
* Try to return the absolute file path of the Gallery video.
*
* #param context
* #param uri
* #return the file path or null
*/
public static String getVideoPathFromGallary(final Context context,Uri contentUri) {
String[] proj = { MediaStore.Video.Media.DATA, MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DURATION};
Cursor cursor = ((Activity) context).managedQuery(contentUri, proj, null, null, null);
if (cursor == null)
return null;
cursor.moveToFirst();
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
int fileSize = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
long duration = TimeUnit.MILLISECONDS.toSeconds(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)));
System.out.println("size: " + fileSize);
System.out.println("duration: " + duration);
return cursor.getString(column_index);
}
very simple !!! you can use glide library.
first add an imageView on videoView and use the code below:
>
GlideApp.with(getApplicationContext()).load("empty")
.thumbnail(GlideApp.with(getApplicationContext()).load("videoURL"))
.into(imageView);
this code will download an image, and eventually, that leads to less internet consumption.

Using setPictureSize and Camera Parameters

I've looked into figuring out how to set the size of a picture, and I stumbled upon CameraParameters and the setPictureSize method associated with it. The problem is, I can't figure out how to use any of these. I don't know what needs to be imported, what object to create, how to use the setPictureSize method, or where to even place that code. I have 2 chunks of code that I feel may be a good place to use setPictureSize. These chunks are:
takePicture = (Button) findViewById(R.id.takePicture);
takePicture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (name.getText().length() == 0 || experimentInput.getText().length() == 0) {
showDialog(DIALOG_REJECT);
return;
}
ContentValues values = new ContentValues();
imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
time = getTime() ;
startActivityForResult(intent, CAMERA_PIC_REQUESTED);
}
});
and:
public static File convertImageUriToFile (Uri imageUri, Activity activity) {
if (activity == null) Log.d("test", "NULL!");
Cursor cursor = null;
try {
String [] proj={MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION};
cursor = activity.managedQuery( imageUri,
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
int file_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
int orientation_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION);
if (cursor.moveToFirst()) {
#SuppressWarnings("unused")
String orientation = cursor.getString(orientation_ColumnIndex);
return new File(cursor.getString(file_ColumnIndex));
}
return null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor!=null)
{
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
else return null;
}
So, my question is, how do I use setPictureSize and where should I put it? No website, nor the android development guide, nor any other related StackOverflow question was helpful to me.
Editted Code:
public Bitmap getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor!=null)
{
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
int desiredImageWidth = 100; // pixels
int desiredImageHeight = 100; // pixels
BitmapFactory.Options o = new BitmapFactory.Options();
o.inSampleSize = 2; // will cut the size of the image in half; OPTIONAL
Bitmap newImage = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(cursor.getString(column_index), o),
desiredImageWidth,
desiredImageHeight,
false);
return newImage; //cursor.getString(column_index);
}
else return null;
}
That's used for when you're actually using the camera through a custom View. What you're doing right here is sending an implicit intent to Android to open another Activity that uses the camera to take a picture.
In this case, you can limit the size of your image by using MediaStore.EXTRA_SIZE_LIMIT. If you want to specify the dimensions of the image, than you have to load it from the URI that it was saved to, create a new scaled image, then resave it over the old one.
Once you have the URI of the image (which is from the DATA attribute in the projection), you can resize the image like so:
int desiredImageWidth = 100; // pixels
int desiredImageHeight = 100; // pixels
BitmapFactory.Options o = new BitmapFactory.Options();
o.inSampleSize = 2; // will cut the size of the image in half; OPTIONAL
Bitmap newImage = Bitmap.createScaleBitmap(BitmapFactory.decodeFile(imagePath, o),
desiredImageWidth,
desiredImageHeight,
false);
Then save it over the old one.

android get real path by Uri.getPath()

I'm trying to get image from gallery.
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select picture"), resultCode );
After I returned from this activity I have a data, which contains Uri. It looks like:
content://media/external/images/1
How can I convert this path to real one (just like '/sdcard/image.png') ?
Thanks
This is what I do:
Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
and:
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
NOTE: managedQuery() method is deprecated, so I am not using it.
Last edit: Improvement. We should close cursor!!
Is it really necessary for you to get a physical path?
For example, ImageView.setImageURI() and ContentResolver.openInputStream() allow you to access the contents of a file without knowing its real path.
#Rene Juuse - above in comments... Thanks for this link !
.
the code to get the real path is a bit different from one SDK to another so below we have three methods that deals with different SDKs.
getRealPathFromURI_API19(): returns real path for API 19 (or above but not tested)
getRealPathFromURI_API11to18(): returns real path for API 11 to API 18
getRealPathFromURI_below11(): returns real path for API below 11
public class RealPathUtil {
#SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri){
String filePath = "";
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
#SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;
CursorLoader cursorLoader = new CursorLoader(
context,
contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if(cursor != null){
int column_index =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
}
return result;
}
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index
= cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
font: http://hmkcode.com/android-display-selected-image-and-its-real-path/
UPDATE 2016 March
To fix all problems with path of images i try create a custom gallery as facebook and other apps. This is because you can use just local files ( real files, not virtual or temporary) , i solve all problems with this library.
https://github.com/nohana/Laevatein (this library is to take photo from camera or choose from galery , if you choose from gallery he have a drawer with albums and just show local files)
Note This is an improvement in #user3516549 answer and I have check it on Moto G3 with Android 6.0.1
I have this issue so I have tried answer of #user3516549 but in some cases it was not working properly.
I have found that in Android 6.0(or above) when we start gallery image pick intent then a screen will open that shows recent images when user select image from this list we will get uri as
content://com.android.providers.media.documents/document/image%3A52530
while if user select gallery from sliding drawer instead of recent then we will get uri as
content://media/external/images/media/52530
So I have handle it in getRealPathFromURI_API19()
public static String getRealPathFromURI_API19(Context context, Uri uri) {
String filePath = "";
if (uri.getHost().contains("com.android.providers.media")) {
// Image pick from recent
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
} else {
// image pick from gallery
return getRealPathFromURI_BelowAPI11(context,uri)
}
}
EDIT1 : if you are trying to get image path of file in external sdcard in higher version then check my question
EDIT2 Here is complete code with handling virtual files and host other than com.android.providers I have tested this method with content://com.adobe.scan.android.documents/document/
EDIT:
Use this Solution here: https://stackoverflow.com/a/20559175/2033223
Works perfect!
First of, thank for your solution #luizfelipetx
I changed your solution a little bit. This works for me:
public static String getRealPathFromDocumentUri(Context context, Uri uri){
String filePath = "";
Pattern p = Pattern.compile("(\\d+)$");
Matcher m = p.matcher(uri.toString());
if (!m.find()) {
Log.e(ImageConverter.class.getSimpleName(), "ID for requested image not found: " + uri.toString());
return filePath;
}
String imgId = m.group();
String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ imgId }, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
Note: So we got documents and image, depending, if the image comes from 'recents', 'gallery' or what ever. So I extract the image ID first before looking it up.
One easy and best method copy file to the real path and then get their path I checked it 10 devices on android API-16 to API-30 working fine.
#Nullable
public static String createCopyAndReturnRealPath(
#NonNull Context context, #NonNull Uri uri) {
final ContentResolver contentResolver = context.getContentResolver();
if (contentResolver == null)
return null;
// Create file path inside app's data dir
String filePath = context.getApplicationInfo().dataDir + File.separator + "temp_file";
File file = new File(filePath);
try {
InputStream inputStream = contentResolver.openInputStream(uri);
if (inputStream == null)
return null;
OutputStream outputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0)
outputStream.write(buf, 0, len);
outputStream.close();
inputStream.close();
} catch (IOException ignore) {
return null;
}
return file.getAbsolutePath();
}
Hii here is my complete code for taking image from camera or galeery
//My variable declaration
protected static final int CAMERA_REQUEST = 0;
protected static final int GALLERY_REQUEST = 1;
Bitmap bitmap;
Uri uri;
Intent picIntent = null;
//Onclick
if (v.getId()==R.id.image_id){
startDilog();
}
//method body
private void startDilog() {
AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(yourActivity.this);
myAlertDilog.setTitle("Upload picture option..");
myAlertDilog.setMessage("Where to upload picture????");
myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
picIntent = new Intent(Intent.ACTION_GET_CONTENT,null);
picIntent.setType("image/*");
picIntent.putExtra("return_data",true);
startActivityForResult(picIntent,GALLERY_REQUEST);
}
});
myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(picIntent,CAMERA_REQUEST);
}
});
myAlertDilog.show();
}
//And rest of things
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==GALLERY_REQUEST){
if (resultCode==RESULT_OK){
if (data!=null) {
uri = data.getData();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
options.inSampleSize = calculateInSampleSize(options, 100, 100);
options.inJustDecodeBounds = false;
Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
imageofpic.setImageBitmap(image);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}else if (requestCode == CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
if (data.hasExtra("data")) {
bitmap = (Bitmap) data.getExtras().get("data");
uri = getImageUri(YourActivity.this,bitmap);
File finalFile = new File(getRealPathFromUri(uri));
imageofpic.setImageBitmap(bitmap);
} else if (data.getExtras() == null) {
Toast.makeText(getApplicationContext(),
"No extras to retrieve!", Toast.LENGTH_SHORT)
.show();
BitmapDrawable thumbnail = new BitmapDrawable(
getResources(), data.getData().getPath());
pet_pic.setImageDrawable(thumbnail);
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}
}
private String getRealPathFromUri(Uri tempUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = this.getContentResolver().query(tempUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null);
return Uri.parse(path);
}
This helped me to get uri from Gallery and convert to a file for Multipart upload
File file = FileUtils.getFile(this, fileUri);
https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
This code work for me in android 11 and 12
private static String getRealPathFromURI(Uri uri, Context context) {
Uri returnUri = uri;
Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String name = (returnCursor.getString(nameIndex));
String size = (Long.toString(returnCursor.getLong(sizeIndex)));
File file = new File(context.getFilesDir(), name);
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
FileOutputStream outputStream = new FileOutputStream(file);
int read = 0;
int maxBufferSize = 1 * 1024 * 1024;
int bytesAvailable = inputStream.available();
//int bufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
final byte[] buffers = new byte[bufferSize];
while ((read = inputStream.read(buffers)) != -1) {
outputStream.write(buffers, 0, read);
}
Log.e("File Size", "Size " + file.length());
inputStream.close();
outputStream.close();
Log.e("File Path", "Path " + file.getPath());
Log.e("File Size", "Size " + file.length());
} catch (Exception e) {
Log.e("Exception", e.getMessage());
}
return file.getPath();
}

Categories

Resources