我如何限制选择的大小图像

时间:2015-12-23 23:25:09

标签: java android android-intent

我的问题是消耗内存,我需要限制所选图像的大小。

修改

我不需要在加载后调整图像大小,我可以使用

调整图像大小
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
      if (requestCode == SELECT_PICTURE) {
        Uri selectedImageUri = data.getData();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

      }
    }
}

我需要阻止用户选择图片> 5 MB

我的代码

public boolean MaxSizeImage(String imagePath) {
    boolean temp = false;
    File file = new File(imagePath);
    long length = file.length();

    if (length < 1500000) // 1.5 mb
        temp = true;

    return temp;
}

限制尺寸文件夹而不是它是更好的选择。

我用这种方法解决了我的问题:

 public String getImagePath(Uri uri){
     Cursor cursor = getContentResolver().query(uri, null, null, null, null);
     cursor.moveToFirst();
     String document_id = cursor.getString(0);
     document_id = document_id.substring(document_id.lastIndexOf(":")+1);
     cursor.close();

     cursor = getContentResolver().query(
             android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
             null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
     cursor.moveToFirst();
     String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
     cursor.close();

     return path;
 }

如果您需要imagePath,可以使用此方法

ERROR: cannot find role in...

5 个答案:

答案 0 :(得分:1)

如果您关心内存消耗,我认为您可以使用Facebook开发的Fresco图像库。在其文档中,您会发现:

  

Fresco是一款用于在Android中显示图像的强大系统   应用。它负责图像加载和显示,所以你不要这样做   必须。

     

Fresco的图像管道将从本地网络加载图像   存储或本地资源。 为了保存数据和CPU,它有三个级别   缓存;两个在内存中,另一个在内部存储中

     

Fresco的Drawees会为您显示占位符,直到图片加载完毕   并在图像到达时自动显示。 当图像   在屏幕外,它会自动释放内存。

然后在功能部分中,您会找到:

  

内存

     

解压缩的图像 - Android位图 - 占用了大量内存。   这导致更频繁地运行Java垃圾收集器。这个   降低应用程序速度。没有这个问题,问题尤其严重   Android 5.0中对垃圾收集器的改进。

     

在Android 4.x及更低版本上,Fresco将图像放在特殊区域   Android内存。它还可以确保图像自动显示   当它们不再显示在屏幕上时从内存中释放。这让我们   您的应用程序运行得更快 - 并且遭受更少的崩溃。

     

使用Fresco的应用程序甚至可以在低端设备上运行而无需运行   不断努力保持他们的形象记忆足迹   控制。

官方网站:http://frescolib.org/

GitHub:https://github.com/facebook/fresco

文章:Introducing Fresco: A new image library for Android

它似乎符合您的需求。这就是我需要写一个答案的原因。

希望有所帮助

答案 1 :(得分:1)

使用类似的东西将图像加载到你想要的内存中,这是使用文件路径,有流方法也可以查看BitmapFactory

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picturePath, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
options.inSampleSize = calculateInSampleSize(options,512,256);//512 and 256 whatever you want as scale
options.inJustDecodeBounds = false;
Bitmap yourSelectedImage = BitmapFactory.decodeFile(selectedImagePath,options);

帮助方法

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) {

    // Calculate ratios of height and width to requested height and width
    final int heightRatio = Math.round((float) height / (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);

    // Choose the smallest ratio as inSampleSize value, this will guarantee
    // a final image with both dimensions larger than or equal to the
    // requested height and width.
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

return inSampleSize;
}

答案 2 :(得分:1)

您可以尝试使用Picasso来获取图片。调用和获取图像时有一个调整大小选项,这可能有助于大小。尽管如此,你可能只限于“一刀切”。它还可以在加载图像时简化许多其他功能,例如占位符,图像无法加载时的错误图像以及其他一些实用程序。

以下是链接的示例请求:

Picasso.with(context)
  .load(url)
  .resize(50, 50)
  .centerCrop()
  .into(imageView)

答案 3 :(得分:1)

试试这个Hackro:D

第一:

public static final int PICK_IMAGE = 1;
private void takePictureFromGalleryOrAnyOtherFolder() 
{
 Intent intent = new Intent();
 intent.setType("image/*");
 intent.setAction(Intent.ACTION_GET_CONTENT);
 startActivityForResult(Intent.createChooser(intent, "Select Picture"),PICK_IMAGE);
}

然后:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
           if (requestCode == PICK_IMAGE) {
                Uri selectedImageUri = data.getData();
                String imagePath = getRealPathFromURI(selectedImageUri);
               //Now you have imagePath do whatever you want to do now
             }//end of inner if
         }//end of outer if
  }

public String getRealPathFromURI(String contentURI) {
    Uri contentUri = Uri.parse(contentURI);

    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = null;
    try {
        if (Build.VERSION.SDK_INT > 19) {
            // Will return "image:x*"
            String wholeID = DocumentsContract.getDocumentId(contentUri);
            // Split at colon, use second item in the array
            String id = wholeID.split(":")[1];
            // where id is equal to
            String sel = MediaStore.Images.Media._ID + "=?";

            cursor = context.getContentResolver().query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    projection, sel, new String[] { id }, null);
        } else {
            cursor = context.getContentResolver().query(contentUri,
                    projection, null, null, null);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    String path = null;
    try {
        int column_index = cursor
                .getColumnIndex(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        path = cursor.getString(column_index).toString();
        cursor.close();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
    return path;
}

答案 4 :(得分:0)

我不知道在选择图像时如何做到这一点,但您可以在选择图像后检查文件大小。

android {
    packagingOptions {
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }
}