android开发中,图片的处理是非常普遍的,经常是需要将用户选择的图片上传到服务器,但是现在手机的分辨率越来越好了,随便一张照片都是2M或以上,如果直接显示到ImageView中,是会出现OOM的,上传到如服务器也会占用大量的流量,用户体验肯定不好了!

下面自己实现了图片的显示以及压缩功能,主要代码是从Volley的ImageRequest中copy过来,作为工具类方便以后图片处理

package com.img.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream; import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore.Images;
import android.util.Log; /**
* 图片压缩工具类
*
* @author Administrator
*
*/
public class ImageCompress { public static final String CONTENT = "content";
public static final String FILE = "file"; /**
* 图片压缩参数
*
* @author Administrator
*
*/
public static class CompressOptions {
public static final int DEFAULT_WIDTH = 400;
public static final int DEFAULT_HEIGHT = 800; public int maxWidth = DEFAULT_WIDTH;
public int maxHeight = DEFAULT_HEIGHT;
/**
* 压缩后图片保存的文件
*/
public File destFile;
/**
* 图片压缩格式,默认为jpg格式
*/
public CompressFormat imgFormat = CompressFormat.JPEG; /**
* 图片压缩比例 默认为30
*/
public int quality = 30; public Uri uri;
} public Bitmap compressFromUri(Context context,
CompressOptions compressOptions) { // uri指向的文件路径
String filePath = getFilePath(context, compressOptions.uri); if (null == filePath) {
return null;
} BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; Bitmap temp = BitmapFactory.decodeFile(filePath, options); int actualWidth = options.outWidth;
int actualHeight = options.outHeight; int desiredWidth = getResizedDimension(compressOptions.maxWidth,
compressOptions.maxHeight, actualWidth, actualHeight);
int desiredHeight = getResizedDimension(compressOptions.maxHeight,
compressOptions.maxWidth, actualHeight, actualWidth); options.inJustDecodeBounds = false;
options.inSampleSize = findBestSampleSize(actualWidth, actualHeight,
desiredWidth, desiredHeight); Bitmap bitmap = null; Bitmap destBitmap = BitmapFactory.decodeFile(filePath, options); // If necessary, scale down to the maximal acceptable size.
if (destBitmap.getWidth() > desiredWidth
|| destBitmap.getHeight() > desiredHeight) {
bitmap = Bitmap.createScaledBitmap(destBitmap, desiredWidth,
desiredHeight, true);
destBitmap.recycle();
} else {
bitmap = destBitmap;
} // compress file if need
if (null != compressOptions.destFile) {
compressFile(compressOptions, bitmap);
} return bitmap;
} /**
* compress file from bitmap with compressOptions
*
* @param compressOptions
* @param bitmap
*/
private void compressFile(CompressOptions compressOptions, Bitmap bitmap) {
OutputStream stream = null;
try {
stream = new FileOutputStream(compressOptions.destFile);
} catch (FileNotFoundException e) {
Log.e("ImageCompress", e.getMessage());
} bitmap.compress(compressOptions.imgFormat, compressOptions.quality,
stream);
} private static int findBestSampleSize(int actualWidth, int actualHeight,
int desiredWidth, int desiredHeight) {
double wr = (double) actualWidth / desiredWidth;
double hr = (double) actualHeight / desiredHeight;
double ratio = Math.min(wr, hr);
float n = 1.0f;
while ((n * 2) <= ratio) {
n *= 2;
} return (int) n;
} private static int getResizedDimension(int maxPrimary, int maxSecondary,
int actualPrimary, int actualSecondary) {
// If no dominant value at all, just return the actual.
if (maxPrimary == 0 && maxSecondary == 0) {
return actualPrimary;
} // If primary is unspecified, scale primary to match secondary's scaling
// ratio.
if (maxPrimary == 0) {
double ratio = (double) maxSecondary / (double) actualSecondary;
return (int) (actualPrimary * ratio);
} if (maxSecondary == 0) {
return maxPrimary;
} double ratio = (double) actualSecondary / (double) actualPrimary;
int resized = maxPrimary;
if (resized * ratio > maxSecondary) {
resized = (int) (maxSecondary / ratio);
}
return resized;
} /**
* 获取文件的路径
*
* @param scheme
* @return
*/
private String getFilePath(Context context, Uri uri) { String filePath = null; if (CONTENT.equalsIgnoreCase(uri.getScheme())) { Cursor cursor = context.getContentResolver().query(uri,
new String[] { Images.Media.DATA }, null, null, null); if (null == cursor) {
return null;
} try {
if (cursor.moveToNext()) {
filePath = cursor.getString(cursor
.getColumnIndex(Images.Media.DATA));
}
} finally {
cursor.close();
}
} // 从文件中选择
if (FILE.equalsIgnoreCase(uri.getScheme())) {
filePath = uri.getPath();
} return filePath;
}
}

使用方式:

<span style="white-space:pre">			</span>ImageCompress compress = new ImageCompress();
ImageCompress.CompressOptions options = new ImageCompress.CompressOptions();
options.uri = imgUri;
options.maxWidth=getWindowManager().getDefaultDisplay().getWidth();
options.maxHeight=getWindowManager().getDefaultDisplay().getHeight();
Bitmap bitmap = compress.compressFromUri(this, options);

默认压缩比例为30%,可以根据实际情况修改。

android 压缩图片大小,防止OOM的更多相关文章

  1. Android --------- 压缩图片的尺寸和大小

    压缩图片大小,尺寸不变 将已知路径的图片压缩至不大于目标大小,并保存至指定路径 /** * 质量压缩,通过给定的路径来压缩图片并保存到指定路径 * * @param srcPath * 资源图片的路径 ...

  2. 关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析

    原文:关于Android中图片大小.内存占用与drawable文件夹关系的研究与分析 相关: Android drawable微技巧,你所不知道的drawable的那些细节 经常会有朋友问我这个问题: ...

  3. Android压缩图片到100K以下并保持不失真的高效方法

    前言:目前一般手机的相机都能达到800万像素,像我的Galaxy Nexus才500万像素,拍摄的照片也有1.5M左右.这么大的照片上传到服务器,不仅浪费流量,同时还浪费时间. 在开发Android企 ...

  4. java 上传图片 并压缩图片大小

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  5. java 上传图片 并压缩图片大小(转)

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  6. 【问题帖】压缩图片大小至指定Kb以下

    像PS,QQ影像等都有该功能,将图片大小压缩至指定kb以下. 我也来山寨一把,到目前为止,控制图片的大小,平时的解决方案通过分辨率和质量来控制的. 假定最后压缩的大小是100kb,那么在保证不大于10 ...

  7. java上传图片并压缩图片大小

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  8. java实现上传图片并压缩图片大小功能

    缩略图压缩文件jar包 <!-- 图片缩略图 --> <dependency> <groupId>net.coobird</groupId> <a ...

  9. 压缩图片大小(Java源码)

    /** * * 直接指定压缩后的宽高: * @param oldFile * 要进行压缩的文件 * @param width * 压缩后的宽度 * @param height * 压缩后的高度 * @ ...

随机推荐

  1. iview使用之怎样通过render函数在table组件表头添加图标及判断多个状态

    在实际项目开发中,我们经常会用到各种各样的表格,比如在表格中填加下拉菜单,按钮,图标及可以根据状态显示对应文字等等,因为这段时间一直在做后台管理系统,所以表格用的就比较多,当然UI组件库我用的是ivi ...

  2. bm25算法和tfidf

  3. Mac home 目录下创建文件夹

    example:sudo vim /etc/auto_master before: # Automounter master map +auto_master # Use directory serv ...

  4. MySQL join的7种理论及SQL写法

    转载于    https://www.cnblogs.com/dinglinyong/p/6656315.html 建表 在这里呢我们先来建立两张有外键关联的张表. CREATE DATABASE d ...

  5. Scala教程之:可扩展的scala

    文章目录 隐式类 限制条件 字符串插值 s 字符串插值器 f 插值器 raw 插值器 自定义插值器 Scala是扩展的,Scala提供了一种独特的语言机制来实现这种功能: 隐式类: 允许给已有的类型添 ...

  6. QML-密码管理器

    Intro 年初刚学Qml时写的密码管理器.用到Socket通信.AES加密等.UI采用Material Design,并实现了Android App的一些常见基本功能,如下拉刷新.弹出提示.再按一次 ...

  7. 【Linux题目】第七关

    1. 如果想修改开机内核参数,应该修改哪个文件? A. /dev/sda1 B. /etc/fstab 磁盘自动挂载的文件 C. /boot/grub/grub.conf D. /etc/rc.loc ...

  8. 【Linux常见命令】route命令

    route - show / manipulate the IP routing table route命令用于显示和操作IP路由表. route命令用来显示并设置Linux内核中的网络路由表,rou ...

  9. 4.pickling 和unpickling是什么?

    pickling 和unpickling是什么? Pickle module accepts any Python object and converts it into a string repre ...

  10. Mybatis自动生成插件对数据库类型为text的处理

    2019独角兽企业重金招聘Python工程师标准>>> 如果数据库中的字段为text或者blob这种大文本类型,在使用MybatisGenerator工具自动生成代码的时候会将其进行 ...