Android 图片压缩,基于比例和质量压缩
package cc.util.android.image; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.util.Log; /**
* A class for helping deal the bitmap,
* like: get the orientation of the bitmap, compress bitmap etc.
* @author wangcccong
* @version 1.140122
* crated at: 2014-03-22
* update at: 2014-06-26
*/
public class BitmapHelper { /**
* get the orientation of the bitmap {@link android.media.ExifInterface}
* @param path
* @return
*/
public final static int getDegress(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
} /**
* rotate the bitmap
* @param bitmap
* @param degress
* @return
*/
public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
if (bitmap != null) {
Matrix m = new Matrix();
m.postRotate(degress);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
return bitmap;
}
return bitmap;
} /**
* caculate the bitmap sampleSize
* @param path
* @return
*/
public final static int caculateInSampleSize(BitmapFactory.Options options, int rqsW, int rqsH) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (rqsW == 0 || rqsH == 0) return 1;
if (height > rqsH || width > rqsW) {
final int heightRatio = Math.round((float) height/ (float) rqsH);
final int widthRatio = Math.round((float) width / (float) rqsW);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
} /**
* 压缩指定路径的图片,并得到图片对象
* @param context
* @param path bitmap source path
* @return Bitmap {@link android.graphics.Bitmap}
*/
public final static Bitmap compressBitmap(String path, int rqsW, int rqsH) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = caculateInSampleSize(options, rqsW, rqsH);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
} /**
* 压缩指定路径图片,并将其保存在缓存目录中,通过isDelSrc判定是否删除源文件,并获取到缓存后的图片路径
* @param context
* @param srcPath
* @param rqsW
* @param rqsH
* @param isDelSrc
* @return
*/
public final static String compressBitmap(Context context, String srcPath, int rqsW, int rqsH, boolean isDelSrc) {
Bitmap bitmap = compressBitmap(srcPath, rqsW, rqsH);
File srcFile = new File(srcPath);
String desPath = getImageCacheDir(context) + srcFile.getName();
int degree = getDegress(srcPath);
try {
if (degree != 0) bitmap = rotateBitmap(bitmap, degree);
File file = new File(desPath);
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 70, fos);
fos.close();
if (isDelSrc) srcFile.deleteOnExit();
} catch (Exception e) {
// TODO: handle exception
Log.e("BitmapHelper-->compressBitmap", e.getMessage()+"");
}
return desPath;
} /**
* 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
* @param is
* @param reqsW
* @param reqsH
* @param isAdjust
* @return
*/
@Deprecated
public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH, boolean isAdjust) {
Bitmap bitmap = BitmapFactory.decodeStream(is);
return compressBitmap(bitmap, reqsW, reqsH, isAdjust);
} /**
* 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象
* @param context
* @param path bitmap source path
* @return Bitmap {@link android.graphics.Bitmap}
*/
public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ReadableByteChannel channel = Channels.newChannel(is);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (channel.read(buffer) != -1) {
buffer.flip();
while (buffer.hasRemaining()) baos.write(buffer.get());
buffer.clear();
}
byte[] bts = baos.toByteArray();
Bitmap bitmap = compressBitmap(bts, reqsW, reqsH);
is.close();
channel.close();
baos.close();
return bitmap;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
} /**
* 压缩指定byte[]图片,并得到压缩后的图像
* @param bts
* @param reqsW
* @param reqsH
* @return
*/
public final static Bitmap compressBitmap(byte[] bts, int reqsW, int reqsH) {
final Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bts, 0, bts.length, options);
options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(bts, 0, bts.length, options);
} /**
* 此方法已过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
* @param bitmap
* @param reqsW
* @param reqsH
* @return
*/
@Deprecated
public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH, boolean isAdjust) {
if (bitmap == null || reqsW == 0 || reqsH == 0) return bitmap;
if (bitmap.getWidth() > reqsW || bitmap.getHeight() > reqsH) {
float scaleX = new BigDecimal(reqsW).divide(new BigDecimal(bitmap.getWidth()), 4, RoundingMode.DOWN).floatValue();
float scaleY = new BigDecimal(reqsH).divide(new BigDecimal(bitmap.getHeight()), 4, RoundingMode.DOWN).floatValue();
if (isAdjust) {
scaleX = scaleX < scaleY ? scaleX : scaleY;
scaleY = scaleX;
}
Matrix matrix = new Matrix();
matrix.postScale(scaleX, scaleY);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return bitmap;
} /**
* 压缩已存在的图片对象,并返回压缩后的图片
* @param bitmap
* @param reqsW
* @param reqsH
* @return
*/
public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, baos);
byte[] bts = baos.toByteArray();
Bitmap res = compressBitmap(bts, reqsW, reqsH);
baos.close();
return res;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return bitmap;
}
} /**
* 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
* get bitmap form resource dictory, and then compress bitmap according to reqsW and reqsH
* @param res {@link android.content.res.Resources}
* @param resID
* @param reqsW
* @param reqsH
* @return
*/
@Deprecated
public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH, boolean isAdjust) {
Bitmap bitmap = BitmapFactory.decodeResource(res, resID);
return compressBitmap(bitmap, reqsW, reqsH, isAdjust);
} /**
* 压缩资源图片,并返回图片对象
* @param res {@link android.content.res.Resources}
* @param resID
* @param reqsW
* @param reqsH
* @return
*/
public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH) {
final Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resID, options);
options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resID, options);
} /**
* 基于质量的压缩算法, 此方法未 解决压缩后图像失真问题
* <br> 可先调用比例压缩适当压缩图片后,再调用此方法可解决上述问题
* @param bts
* @param maxBytes 压缩后的图像最大大小 单位为byte
* @return
*/
public final static Bitmap compressBitmap(Bitmap bitmap, long maxBytes) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, baos);
int options = 90;
while (baos.toByteArray().length > maxBytes) {
baos.reset();
bitmap.compress(CompressFormat.PNG, options, baos);
options -= 10;
}
byte[] bts = baos.toByteArray();
Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length);
baos.close();
return bmp;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
} // public final static Bitmap compressBitmap(InputStream is, long maxBytes) {
// try {
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// byte[] bts = new byte[1024];
// while (is.read(bts) != -1) baos.write(bts, 0, bts.length);
// is.close();
// int options = 100;
// while (baos.toByteArray().length > maxBytes) {
//
// }
// } catch (Exception e) {
// // TODO: handle exception
// }
// } /**
* 得到指定路径图片的options
* @param srcPath
* @return Options {@link android.graphics.BitmapFactory.Options}
*/
public final static Options getBitmapOptions(String srcPath) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcPath, options);
return options;
} /**
* 获取图片缓存路径
* @param context
* @return
*/
private static String getImageCacheDir(Context context) {
String dir = FileHelper.getCacheDir(context) + "Image" + File.separator;
File file = new File(dir);
if (!file.exists()) file.mkdirs();
return dir;
}
}
Android 图片压缩,基于比例和质量压缩的更多相关文章
- Android中图片压缩(质量压缩和尺寸压缩)
关于Android 图片压缩的学习: 自己总结分为质量压缩和像素压缩.质量压缩即:将Bitmap对象保存到对应路径下是所占用的内存减小,但是当你重新读取压缩后的file为Bitmap时,它所占用的内存 ...
- Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩
目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...
- Android图片压缩方法总结
本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩). 第一:质量压缩方法: ? 1 2 3 ...
- android图片压缩方法
android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...
- android图片压缩的3种方法实例
android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...
- 性能优化——Android图片压缩与优化的几种方式
图片优化压缩方式大概可以分为以下几类:更换图片格式,质量压缩,采样率压缩,缩放压缩,调用jpeg压缩等1.设置图片格式Android目前常用的图片格式有png,jpeg和webp,png:无损压缩图片 ...
- android图片压缩总结
一.bitmap 图片格式介绍 android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: bitmap内存大 ...
- Android 图片压缩各种方式
前言:由于公司项目当中需要用到压缩这块的相应技术,之前也做过的图片压缩都不是特别的理想, 所以这次花了很多心思,仔细研究和在网上找到了很多相对应的资料.为了就是 以后再做的时候直接拿来用就可以了 ...
- 利用反射快速给Model实体赋值 使用 Task 简化异步编程 Guid ToString 格式知多少?(GUID 格式) Parallel Programming-实现并行操作的流水线(生产者、消费者) c# 无损高质量压缩图片代码 8种主要排序算法的C#实现 (一) 8种主要排序算法的C#实现 (二)
试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...
随机推荐
- halt---关闭正在运行的Linux操作系统。
halt命令用来关闭正在运行的Linux操作系统.halt命令会先检测系统的runlevel,若runlevel为0或6,则关闭系统,否则即调用shutdown来关闭系统. 语法 halt(选项) 选 ...
- Android实战简易教程-第二十五枪(基于Baas的数据表查询下拉刷新和上拉载入实现!)
上一节我们实现了数据表的载入,可是,当数据表数据非常多时.我们就要考虑数据的分页.这里我们选用了PullToRefreshListView控件,先看一下该控件的说明: 效果图: ...
- 缩放文本框ExpandTextView
效果图: 代码: import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import ...
- Android 阅读器架构图,网上收集,留做存货
这个结构图是网上收集的图片.基结构明晰简洁.易于后期维护.本文会继续收集很多其他其他优秀的结构图,望有图的朋友推荐~
- iTOP-4412开发板使用
使用环境:win7 旗舰64位,VMware11 使用使用板上提供的ubuntu12.04,用VMWARE直接打开虚拟机,因为之前开发epc9600开发板,所以虚拟机网络已经设置过,加载ubuntu1 ...
- JS/CSS 在屏幕底部弹出消息
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...
- 【AIM Tech Round 4 (Div. 2) C】Sorting by Subsequences
[链接]http://codeforces.com/contest/844/problem/C [题意] 水题,没有记录意义 [题解] 排序之后,记录每个数字原来在哪里就好. 可以形成环的. 环的个数 ...
- 4.auto详解
#include <iostream> using namespace std; template <calss T1,class T2> auto add(T1 t1, T2 ...
- docker第一章
简介 Docker 是 Docker.Inc 公司开源的一个基于 LXC技术之上构建的Container容器引擎, 源代码托管在 GitHub 上, 基于Go语言并遵从Apache2.0协议开源. D ...
- 使用solr的DIHandler 构建mysql大表全量索引,内存溢出问题的解决方法
solr官方给出的解决方式是: DataImportHandler is designed to stream row one-by-one. It passes a fetch size value ...