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. 硬盘性能测试工具之bonnie++

    bonnie++ 官方站点 先写内存的两倍,内存较大时比较耗时.适合简单的测试场景. # bonnie++ -u root 写测试 读测试 Version 1.97 ------Sequential ...

  2. 最通俗易懂的Redis发布订阅及代码实战

    发布订阅简介 除了使用List实现简单的消息队列功能以外,Redis还提供了发布订阅的消息机制.在这种机制下,消息发布者向指定频道(channel)发布消息,消息订阅者可以收到指定频道的消息,同一个频 ...

  3. Linux必须会的命令---也是以前记录的,ctrl+z fg 啥的 jobs 比较实用

    fg.bg.jobs.&.ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的 一.& 最经常被用到 这个用在一个命令的最后,可以把这个命令 ...

  4. 前端基础进阶(六)-大厂面试题问题:循环闭包与setTimeout

    我在上一篇闭包的文章中留下了一个关于setTimeout与循环闭包的思考题. 利用闭包,修改下面的代码,让循环输出的结果依次为1, 2, 3, 4, 5 for (var i = 1; i <= ...

  5. 3.k均值的算法

    一.课堂练习 # 课堂练习 from sklearn.datasets import load_iris # 导入鸢尾花数据 iris=load_iris() iris iris.keys() dat ...

  6. Inno Setup [Run] Section 双引号嵌套

    https://stackoverflow.com/questions/26257808/inno-setup-how-to-run-a-code-procedure-in-run-section-o ...

  7. PAT A1023

    简单的大数问题,long long并不能容纳21位数字,这是刚开始没有注意到的 #include<iostream> #include<stdlib.h> #include&l ...

  8. embed git commit hash to assembly

    https://stackoverflow.com/a/41200059/3782855 https://github.com/304NotModified/Fody.Stamp

  9. 日日算法:Dijkstra算法

    介绍 Dijistra算法作为一种最短路径算法,可以用来计算一个节点到图上其他节点的最短距离. 主要是通过启发式的思想,由中心节点层层向外拓展,直到找到中点. 适用于无向图和有向图. 算法思想 假设我 ...

  10. Modbus TCP协议说明

    协议帧 事物处理标识| 协议标识| 长度| 从机地址| 功能码| 数据 0x00 00| 0x00 00| 0x00 08| 0x01| 0x0F| 0x00 14 0x00 01 0x01 0x01 ...