Android图片压缩

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.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore.Images;
import android.util.Log;
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;
}
}
ImageCompress.java
调用方式:
Object srcPath; // 源图片,可以是sdcard文件路径,也可以是图片库的Uri
String dstPath; // 压缩后的保存路径
CompressOptions options = new CompressOptions();
options.destFile = new File(dstPath);
options.maxWidth = 1000;
options.maxHeight = 1280;
options.uri = (srcPath instanceof Uri) ? ((Uri)srcPath) : Uri.fromFile(new File(srcPath.toString()));
Bitmap bitMap = new ImageCompress().compressFromUri(context, options);
Android图片压缩的更多相关文章
- Android 图片压缩、照片选择、裁剪,上传、一整套图片解决方案
1.Android一整套图片解决方案 http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820998&idx=1& ...
- android图片压缩方法
android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...
- android图片压缩的3种方法实例
android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...
- Android 图片压缩器
概述 Android 图片压缩器:一款高效的图片压缩器库,支持批量压缩,异步压缩.多线程多任务压缩,压缩比设置等特性. 详细 代码下载:http://www.demodashi.com/demo/12 ...
- Android 图片压缩各种方式
前言:由于公司项目当中需要用到压缩这块的相应技术,之前也做过的图片压缩都不是特别的理想, 所以这次花了很多心思,仔细研究和在网上找到了很多相对应的资料.为了就是 以后再做的时候直接拿来用就可以了 ...
- Android图片压缩上传(二)
之前有用到libjpeg,还是有一定的局限性,最近用了一个新的方式,效果还是挺不错,随着作者的版本更新,Bug也随之变少,目前项目中运用已上线. 1.之前的方式Android图片压缩,不失真,上线项目 ...
- Android图片压缩方法总结
本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩). 第一:质量压缩方法: ? 1 2 3 ...
- 性能优化——Android图片压缩与优化的几种方式
图片优化压缩方式大概可以分为以下几类:更换图片格式,质量压缩,采样率压缩,缩放压缩,调用jpeg压缩等1.设置图片格式Android目前常用的图片格式有png,jpeg和webp,png:无损压缩图片 ...
- android图片压缩总结
一.bitmap 图片格式介绍 android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: bitmap内存大 ...
随机推荐
- HDOJ多校联合第四场
B题: C题:仅由'A','G','C','T',4个字母组成,给定一个字符串S,|S|<=15,给定一个整数m,以m为长度且仅含4种字母的字符串T,求LCS(S,T)为0,1,2,3....| ...
- 156. Binary Tree Upside Down
题目: Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node ...
- 【Linux安全】系统资源监控与进程终止
linux系统允许多用户同时操作,当用户量非常大且占用系统资源非常严重的时候, 管理员想要分析一下资源的占用情况,而在linux中有没有类似于windows系统的 资源管理器一样的工具呢,答案是肯定的 ...
- [Hadoop源码解读](二)MapReduce篇之Mapper类
前面在讲InputFormat的时候,讲到了Mapper类是如何利用RecordReader来读取InputSplit中的K-V对的. 这一篇里,开始对Mapper.class的子类进行解读. 先回忆 ...
- 抽离CodeIgniter的数据库访问类 可以独立使用
好吧,因为组织需要,最近又开始转战php了,业务逻辑都还好说,主要是老大要求在数据访问层上加上登录态验证.其实这种要求也是合理的,互联网服务要求上层保护下层,但下层不能完全相信上层.但是问题也就来了, ...
- Chrome已原生支持“Chrome To Mobile”
完成PC和手机端Chrome的同gmail帐号绑定后,即可按如下操作进行: 已知在版本“19.0.1084.15”中,这个功能默认未开启,需要进入“chrome://flags/”进行手工启用(早几期 ...
- SQL_Server2005自动备份与删除—维护计划
业务背景: 为了方便客户及时自动更新SAP库里面的数据与减少磁盘的空间.所以要在SQL对数据进行自动备份与删除备份.这样可以更加方便管理员的管理,和减少管理员的工作量. 解决思路: 在2005 SQL ...
- Android What is Application
本文转自:http://www.cnblogs.com/elleniou/archive/2012/05/16/2502661.html Application和Activity,Service一样是 ...
- ruby编程语言-学习笔记1
安装完 ruby ri irb ruby-devel 1. 先来个简单的,写个helloworld 给新手们 (terminal中,# 代表root权限,$ 代表用户权限, 前面的就不写了.) # ...
- [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.1.1
Given any $k$-tupel of linearly independent vectors $X$ as above, there exists a $k$-tuple $Y$ biort ...