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. ES6的 Iterator 遍历器到底是什么?

    这节课要讲的是ES6中的Iterator. for...of为啥不遍历Object对象 第十三节我们讲了简单又实用的for...of,我们可以使用它来遍历数组,字符串,Set和Map结构,但是有没有发 ...

  2. 关于virtualbox配置centos7的网络问题

    连接方式最好选桥接网卡 原文:https://www.cnblogs.com/zergling9999/p/6026006.html

  3. 基于centos7搭建kvm

    其他的和安装一般的系统没有差别 安装完成后. 1]使用ping www.baidu.com 2]修改静态ip,也可以不修改 3]下载brctlyum -y install bridge-utils 4 ...

  4. 对 ThreadLocal 的了解(一)

    Threadlocal ThreadLocal 在我个人理解范围内,主要作用是在同一个线程里面,去共享某个数据给这个线程在不同的阶段去使用. 本次使用范围 在集成 pageOffice 在线 word ...

  5. java 之 构造器 static关键字

    构造器  特点: 方法名和类名一至,没有void没有返回,无参数的称为无参构造器,有参数的称为有参构造器 语法: public 类名 {数据类型 参数名} 目的:创建对象 注意:如果类中没有带有参数的 ...

  6. SSH公钥登录和RSA非对称加密

    SSH登录方式 接触过Linux服务器的同学肯定用过SSH协议登录系统,通常SSH协议都有两种登录方式:密码口令登录和公钥登陆. 一.密码口令(类似于账号密码登录) 1.客户端连接服务器,服务器把公钥 ...

  7. WSFC与DFS

    WSFC里面的文件服务器群集,文件始终是一份,数据始终存放在群集磁盘中,通过群集来维持文件服务器这项服务始终持续可用,在2012之前同一时间WSFC只能有一台节点对外提供文件服务,2012开始群集引入 ...

  8. 是时候实现 SOC 2.0 了

    本文讲的是是时候实现 SOC 2.0 了,SOC,安全运营中心,为取得其最佳效果,以及真正最小化网络风险,需要全员就位,让安全成为每个人的责任. 早在几年前,企业就开始创建SOC来集中化威胁与漏洞的监 ...

  9. JS中switch语句做选择时为什么可以不用break?

    在JavaScript中,switch语句相比其他语言并没有特殊之处. 在使用时,我们要注意每个分支后都应加一条break语句,否则后面的分支仍然会执行.实际程序中,我发现有时没用break语句,仍然 ...

  10. #Week3 Linear Regression with Multiple Variables

    一.Multiple Features 这节课主要引入了一些记号,假设现在有n个特征,那么: 为了便于用矩阵处理,令\(x_0=1\): 参数\(\theta\)是一个(n+1)*1维的向量,任一个训 ...