7

I am selecting an image from gallery.I want to determine the size of the image programatically in kb or mb. This is what I have written:

public String calculateFileSize(Uri filepath)
{
    //String filepathstr=filepath.toString();
    File file = new File(filepath.getPath());

    // Get length of file in bytes
    long fileSizeInBytes = file.length();
    // Convert the bytes to Kilobytes (1 KB = 1024 Bytes)
    long fileSizeInKB = fileSizeInBytes / 1024;
    // Convert the KB to MegaBytes (1 MB = 1024 KBytes)
    long fileSizeInMB = fileSizeInKB / 1024;

    String calString=Long.toString(fileSizeInMB);
    return calString;
}

The uri of the image when selected from gallery is coming perfectly.But the value of fileSizeInBytes is zero.I am calling this method on onActivityResult ,after selecting the image from gallery.I saw a few same questions asked here before.But none worked for me.Any solution?

kgandroid
  • 5,507
  • 5
  • 39
  • 69

7 Answers7

5

Change

public String calculateFileSize(Uri filepath)
{
  //String filepathstr=filepath.toString();
  File file = new File(filepath.getPath());

  long fileSizeInKB = fileSizeInBytes / 1024;
  // Convert the KB to MegaBytes (1 MB = 1024 KBytes)
  long fileSizeInMB = fileSizeInKB / 1024;

  String calString=Long.toString(fileSizeInMB);

to

public String calculateFileSize(String filepath)
{
  //String filepathstr=filepath.toString();
  File file = new File(filepath);

  float fileSizeInKB = fileSizeInBytes / 1024;
  // Convert the KB to MegaBytes (1 MB = 1024 KBytes)
  float fileSizeInMB = fileSizeInKB / 1024;

  String calString=Float.toString(fileSizeInMB);

When you use long it will truncate all the digits after . So if your size is of less than 1MB you will get 0.

So instead use float in place of long

Apoorv
  • 13,470
  • 4
  • 27
  • 33
  • 2
    Thanks for your reply.Not working.value of fileSizeInBytes returning 0.0....The uri is /external/images/media/1243 – kgandroid Jul 21 '14 at 12:01
  • That is a path not an `Uri`. Check [fromFile](http://developer.android.com/reference/android/net/Uri.html#fromFile(java.io.File)) to see what a `Uri` looks like – Apoorv Jul 21 '14 at 12:05
  • then how can i get the size from imagepath??is it possible?? – kgandroid Jul 21 '14 at 12:07
  • Check the edited answer. You need to change your argument and the way you create a `File` – Apoorv Jul 21 '14 at 12:09
4

Just try this one and it will work for you

private void getImageSize(Uri choosen) throws IOException {
        Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), choosen);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] imageInByte = stream.toByteArray();
        long lengthbmp = imageInByte.length;

        Toast.makeText(getApplicationContext(),Long.toString(lengthbmp),Toast.LENGTH_SHORT).show();

    }

And on result

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch(requestCode) {
            case SELECT_PHOTO:
                if(resultCode == RESULT_OK){
                    Uri selectedImage = data.getData();

                    if(selectedImage !=null){

                        img.setImageURI(selectedImage);

                        try {
                            getImageSize(choosenPhoto);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        //txt1.setText("Initial size: " +getImageSize(choosenPhoto)+ " Kb");
                    }
                }
        }
    }
Daniel Nyamasyo
  • 2,152
  • 1
  • 24
  • 23
3

It is a method for calculating image size chosen from the gallery. you can pass the Uri which you get from intent in onActivityResult :

public static double getImageSizeFromUriInMegaByte(Context context, Uri uri) {
    String scheme = uri.getScheme();
    double dataSize = 0;
    if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
        try {
            InputStream fileInputStream = context.getContentResolver().openInputStream(uri);
            if (fileInputStream != null) {
                dataSize = fileInputStream.available();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else if (scheme.equals(ContentResolver.SCHEME_FILE)) {
        String path = uri.getPath();
        File file = null;
        try {
            file = new File(path);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (file != null) {
            dataSize = file.length();
        }
    }
    return dataSize / (1024 * 1024);
}
3

use uri.getLastPathSegment() instead of uri.getPath()

public static float getImageSize(Uri uri) {

    File file = new File(uri.getLastPathSegment());
    return file.length(); // returns size in bytes
}

IMPORTANT

The above code will only work for images that you pick from gallery; and doesn't work for those from file manager as it won't recognize the scheme of the URI

The below method will work in either case

public static float getImageSize(Context context, Uri uri) {
    Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
    if (cursor != null) {
        int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
        cursor.moveToFirst();
        float imageSize = cursor.getLong(sizeIndex);
        cursor.close();
        return imageSize; // returns size in bytes
    }
    return 0;
}

To change from bytes into Kbytes >>> /1024f

To change from bytes into Mbytes >>> /(1024f * 1024f)

Zain
  • 37,492
  • 7
  • 60
  • 84
  • Above solution is also mentioned in their official documentation https://developer.android.com/training/secure-file-sharing/retrieve-info as well. So feel free to use it. Happy coding :) – Smeet Nov 05 '19 at 09:44
  • 1
    @Smeet thanks for your added value appreciate it :) – Zain Nov 05 '19 at 11:55
0
private boolean validImageSize() {
        try {
            if (bitmapPhoto!=null){
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmapPhoto.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byte[] imageInByte = stream.toByteArray();


                // Get length of file in bytes
                float imageSizeInBytes = imageInByte.length;
                // Convert the bytes to Kilobytes (1 KB = 1024 Bytes)
                float imageSizeInKB = imageSizeInBytes / 1024;
                // Convert the KB to MegaBytes (1 MB = 1024 KBytes)
                float imageSizeInMB = imageSizeInKB / 1024;
                return imageSizeInMB <= 1;
            }else {
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
            return true;

        }

    }
ilidiocn
  • 323
  • 2
  • 5
0

Try this it will return to you file from uri in new android and older

fun getFileFromUri(uri: Uri): File? {
if (uri.path == null) {
    return null
}
var realPath = String()
val databaseUri: Uri
val selection: String?
val selectionArgs: Array<String>?
if (uri.path!!.contains("/document/image:")) {
    databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    selection = "_id=?"
    selectionArgs = arrayOf(DocumentsContract.getDocumentId(uri).split(":")[1])
} else {
    databaseUri = uri
    selection = null
    selectionArgs = null
}
try {
    val column = "_data"
    val projection = arrayOf(column)
    val cursor = context.contentResolver.query(
        databaseUri,
        projection,
        selection,
        selectionArgs,
        null
    )
    cursor?.let {
        if (it.moveToFirst()) {
            val columnIndex = cursor.getColumnIndexOrThrow(column)
            realPath = cursor.getString(columnIndex)
        }
        cursor.close()
    }
} catch (e: Exception) {
    Log.i("GetFileUri Exception:", e.message ?: "")
}
val path = if (realPath.isNotEmpty()) realPath else {
    when {
        uri.path!!.contains("/document/raw:") -> uri.path!!.replace(
            "/document/raw:",
            ""
        )
        uri.path!!.contains("/document/primary:") -> uri.path!!.replace(
            "/document/primary:",
            "/storage/emulated/0/"
        )
        else -> return null
    }
}
return File(path)}

and after you can use this for get file size

val file = getFileFromUri(your_uri)
val file_size = Integer.parseInt(String.valueOf(file.length()/1024))
Mahdi Zareei
  • 1,299
  • 11
  • 18
0

In recent versions of Android there are many limitations for accessing direct file. We can use ContentProviders to get the size from Uri. Refer here

 fun getFileSize(uri: Uri): Long {
    val cursor: Cursor? = context.contentResolver!!.query(
        yourFileUri, null, null, null, null
    )

    cursor?.use {
        val sizeColumn =
            it.getColumnIndexOrThrow(android.provider.MediaStore.MediaColumns.SIZE)
        if (it.moveToNext()) {
            return it.getLong(sizeColumn)
        }
    }
    return 0L
 }

you can also use below function to format the size

android.text.format.Formatter.formatFileSize(context: Context?, sizeBytes: Long): String!

shobhan
  • 1,460
  • 2
  • 14
  • 28