有关图片的压缩,整理一下.有用的COPY


工具两个类. ImageHelp 与 ImageHelp
调用方法MainActivity
直接贴代码了

ImageHelp

package com.myetc.bitmapuse;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;/*** 图片压缩工具类* 1:指定res中的id进行压缩* 2:指定bitmap进行压缩* 3:指定path 进行压缩* @author lixifeng* 声明:要有SD卡的读存权限*/
public class ImageHelp  {private static String TEMP_PATH = "sdcard/aboutimage/temp";private static int maxFileSize_KB =200;//图片压缩大小最终文件大小<maxFileSize_KBprivate static int imageSizeW_H =1000*2000;//图片压缩大小区间 指在x*y<imageSizeW_H 而不是边长固定/*** 压缩图片并保存到文件* @param context 页面* @param pathInput SD卡形式的图片路径 (注:要压缩的图片)* @param pathOutput SD形貌的图片路径 (注:压缩后图片存放的位置)* @param max 压缩指定最大的边(注:0:不取最大边.以 imageSizeW_H 为准)* * imageSizeW_H 默认为:1000*2000* maxFileSize_KB 默认为200KB * */public  void resampleImageAndSaveToNewLocation(final Context context,final String pathInput, final String pathOutput,int max) {resampleImageAndSaveToNewLocation(context, 0, null,pathInput, pathOutput,max);}/*** 压位图并保存到文件* @param context 页面* @param bitmap 位图* @param pathOutput SD形貌的图片路径 (注:压缩后图片存放的位置)* @param max 压缩指定最大的边(注:0:不取最大边.以 imageSizeW_H 为准)* * imageSizeW_H 默认为:1000*2000* maxFileSize_KB 默认为200KB * */public  void resampleImageAndSaveToNewLocation(final Context context,final Bitmap bitmap, final String pathOutput,int max) {resampleImageAndSaveToNewLocation(context, 0, bitmap,null, pathOutput,max);}/*** 压位图并保存到文件* @param context 页面* @param id res资源下的id* @param pathOutput SD形貌的图片路径 (注:压缩后图片存放的位置)* @param max 压缩指定最大的边(注:0:不取最大边.以 imageSizeW_H 为准)* * imageSizeW_H 默认为:1000*2000* maxFileSize_KB 默认为200KB * */public  void resampleImageAndSaveToNewLocation(final Context context,final int id, final String pathOutput,int max){resampleImageAndSaveToNewLocation(context, id, null, null,pathOutput,max);}/*** 压缩进度的监听 注:子线程.不可操作UI,如要主线程,自行结耦* @param imageHelpListen*/public void setImageHelpListen(ImageHelpListen imageHelpListen) {ImageHelpListen = imageHelpListen;}/*** 把资源文件,保存到sd卡中* * @param context* @param id* @param pathOutput* @param max 指定最大边 注:max!=0 imageSizeW_H刚失效 0:无效* @throws Throwable*/private  void resampleImageAndSaveToNewLocation(final Context context,final int id, final Bitmap bitmap,final String pathInput,final String pathOutput,final int max)  {//创建一个线程,去执行当前的任务new Thread(new ImageHelpRun(){@Overridepublic void run() {super.run();String temp_ =  TEMP_PATH+"/"+System.currentTimeMillis()+".jpg";setState(State.START,null);//第一步,把资源保存到文件中去try {setState(State.ING,null);resampleImageAndSaveToNewLocation(context, id, bitmap, pathInput,temp_);} catch (Throwable e) {setState(State.ERROR,e);}//第二步,以当前的路径 ,压缩图片try {resampleImageAndSave(maxFileSize_KB, temp_, pathOutput, imageSizeW_H,max);setState(State.SUCCESS,null);//删除缓存try {new File(temp_).delete();} catch (Throwable e) {System.err.println("删除缓存失败");}} catch (Throwable e) {setState(State.ERROR,e);}}}).start();}private void setState(State state,Throwable e){if(ImageHelpListen!=null){ImageHelpListen.getState(state ,e);;}}ImageHelpListen ImageHelpListen;public interface ImageHelpListen{public void getState(State state, Throwable e);}public static String getTEMP_PATH() {return TEMP_PATH;}public static void setTEMP_PATH(String tEMP_PATH) {TEMP_PATH = tEMP_PATH;}public static int getMaxFileSize_KB() {return maxFileSize_KB;}public static void setMaxFileSize_KB(int maxFileSize_KB) {ImageHelp.maxFileSize_KB = maxFileSize_KB;}public static int getImageSizeW_H() {return imageSizeW_H;}public static void setImageSizeW_H(int imageSizeW_H) {ImageHelp.imageSizeW_H = imageSizeW_H;}public enum State{ START, ING, SUCCESS, ERROR };}

ImageHelpRun

package com.myetc.bitmapuse;import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Build;
import android.util.Log;public class ImageHelpRun implements Runnable{//文件流,所执行的步长private static final int moveSize = 2048;/*** 把资源文件,或者位图 保存到sd卡中* @param context* @param id 资源ID* @param bitmap 位置* @param pathOutput 输出位置* @throws Throwable */public  void resampleImageAndSaveToNewLocation(Context context,int id,Bitmap bitmap,String pathInput,String pathOutput) throws Throwable {if(context==null) throw new NullPointerException("context is null");if(pathOutput==null) throw new NullPointerException("pathOutput is null");File file = new File(pathOutput);//创建文件//如果文件不存在就创建文件,写入图片if (!file.exists()) {//注:如果没有权限,不会被提示file.getParentFile().mkdirs();}else{file.delete();}if(id!=0){//读取程序中的图片 保存到 pathOutput 的文件中去copyIO(context.getResources().openRawResource(id), new FileOutputStream(file));}else if(bitmap!=null){//把bitmap 转为is , 保存到 pathOutput 的文件中去copyIO(Bitmap2IS(bitmap), new FileOutputStream(file));}else if(pathInput!=null){copyIO(new FileInputStream(pathInput), new FileOutputStream(file));}else{throw new NullPointerException("no file??????????");}}@Overridepublic void run() {}/*** * @param maxFileSize_KB 指定保存图片的大小 * @param pathInput 图片所有的位置 * @param pathOutput 图片要保存的位置* @param imageSizeW_H 图片的w*h的积* @return* @throws Exception*/public  Bitmap resampleImageAndSave(int maxFileSize_KB,String pathInput,String pathOutput,double imageSizeW_H,int maxDim) throws Throwable{//计算当前文件,是否达标if(verFile(new File(pathInput), maxFileSize_KB)<=0){//如果文件达标,不用压缩,直接COPY走copyFile(pathInput, pathOutput);return null;}else{//图片超出指定kbSystem.out.println(" ");System.out.println(" ");System.out.println("*****读取缩放比例*****");BitmapFactory.Options opts = new BitmapFactory.Options();//只取图片的尺寸opts.inJustDecodeBounds = true;BitmapFactory.decodeFile(pathInput, opts);//w*h小于imageSizeW_H 例:100*200<2000*80 不进行缩放if(opts.outWidth*opts.outHeight<=imageSizeW_H){//设置不缩放opts.inSampleSize = 1;}else{//假设 图片等比例压缩,大小为1080*1920 开方结果为 1440//得到以1440为最大边的图片压缩图int max = (int) Math.sqrt(imageSizeW_H);//计算出图片的等比缩放等级1-xopts.inSampleSize = getClosestResampleSize(opts.outWidth,opts.outHeight, max);}//进行取图,包含内容opts.inJustDecodeBounds = false;//取得图片.这里可能会内存OOM ,做处理System.out.println(" ");System.out.println(" ");System.out.println("*****加载图片*****");Bitmap bit = null;boolean loadImage = true;//开关...你懂的..//在这里,进行循环压缩do {try {//取到图片bit = BitmapFactory.decodeFile(pathInput, opts);loadImage = false;} catch (OutOfMemoryError e) {//如果缩放(或缩放为1)情况下,也oom,进行缩放递增loadImage = true;//缩放图片,进行加载opts.inSampleSize = opts.inSampleSize+1;}} while (loadImage);/** 注:::::::::这里确定取到了bitmap.而没有异常* */System.out.println(" ");System.out.println(" ");System.out.println("*****旋转图片*****");//判断图片是否被旋转了,如果旋转,进行反转图片bit = resampleImage(bit, maxDim, pathInput);System.out.println(" ");System.out.println(" ");System.out.println("*****保存缩放后的图片*****");int quality = 100;if(opts.inSampleSize==1){//如果没有改变大小,改变质量,质量以输入的10% 降//保存完之后,验证是否符合标准quality  = 90;}else{//用来重原图开始//因为用了do while,所在进行添加一次上限的值,进行保存原图quality  = 100;}int dif = 20;//每次在原图的基本上读取的等级 100 80 60 40 20 0//如何快速计算出质量比double difKB = 0;do {//保存图片的方法,要进行升级File file = new File(pathOutput);if (!file.exists()) {//注:如果没有权限,不会被提示file.getParentFile().mkdirs();}else{file.delete();}OutputStream out = new FileOutputStream(file);//压缩图片质量,在原图上bit.compress(Bitmap.CompressFormat.JPEG, quality, out);//保存到图片达标difKB = verFile(file, maxFileSize_KB);quality-=dif;} while (difKB>0);System.out.println(" ");System.out.println(" ");System.out.println("*****完成*****");return bit;}}/***  图片压缩,旋转* @param bmpt 指定的bit * @param maxDim 指定压缩大小 0:只压缩只旋转* @param pathInput 图片所在的位置* @return* @throws Exception*/public  Bitmap resampleImage(Bitmap bmpt, int maxDim,String pathInput)throws Exception {Matrix m = new Matrix();int sdk = new Integer(Build.VERSION.SDK).intValue();if (sdk > 4) {//图片旋转int rotation = readPictureDegree(pathInput);if (rotation != 0) {//进行旋转m.postRotate(rotation);}}if(maxDim!=0){BitmapFactory.Options optsScale = getResampling(bmpt.getWidth(),bmpt.getHeight(), maxDim);m.postScale((float) optsScale.outWidth / (float) bmpt.getWidth(),(float) optsScale.outHeight / (float) bmpt.getHeight());}return Bitmap.createBitmap(bmpt, 0, 0, bmpt.getWidth(),bmpt.getHeight(), m, true);}/*** 计算由指定最大边,应改变的大小* @param cx 宽* @param cy 高* @param max 最大的一个边* @return*/private  BitmapFactory.Options getResampling(int cx, int cy, int max) {float scaleVal = 1.0f;BitmapFactory.Options bfo = new BitmapFactory.Options();if (cx > cy) {scaleVal = (float) max / (float) cx;} else if (cy > cx) {scaleVal = (float) max / (float) cy;} else {scaleVal = (float) max / (float) cx;}bfo.outWidth = (int) (cx * scaleVal + 0.5f);bfo.outHeight = (int) (cy * scaleVal + 0.5f);return bfo;}/*** 把bitmap 转换为 is* @param bm* @return*/public InputStream Bitmap2IS(Bitmap bm) {ByteArrayOutputStream baos = new ByteArrayOutputStream();bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);InputStream sbs = new ByteArrayInputStream(baos.toByteArray());return sbs;}/*** 读取图片的旋转角度(注:不会30度45度)* @param path 图片所在的路径 (注:用路径,是最高性能的读取,用bitmap什么的,内存会疯掉的)* @return 返回:角度*/public  int readPictureDegree(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;}/*** 计算图片在指定边的情况下,缩放等级* @param cx 宽* @param cy 高* @param maxDim 指定大小* @return 返回:缩放等级  2,缩小2倍 3,3倍*/private  int getClosestResampleSize(int cx, int cy, int maxDim) {int max = Math.max(cx, cy);int resample = 1;for (resample = 1; resample < Integer.MAX_VALUE; resample++) {if (resample * maxDim > max) {resample--;break;}}if (resample > 0) {return resample;}return 1;}/**  * 复制单个文件  * @param oldPath String 原文件路径 如:c:/fqf.txt  * @param newPath String 复制后路径 如:f:/fqf.txt  * @return   注:会oom*/   private   void copyFile(String oldPath, String newPath) throws Throwable {   File oldfile = new File(oldPath);   if (oldfile.exists()) { //文件存在时   //进行copycopyIO(new FileInputStream(oldPath), new FileOutputStream(newPath));  }else{throw new NotFoundException("no foud oldPath");}}  /*** 流文件的copy* @param is 输入流* @param os 输出流*/private  void copyIO(InputStream is,FileOutputStream os ) throws Throwable{//移动步长byte[] buffer = new byte[moveSize]; int count = 0; //以 buffer 进行写入while((count=is.read(buffer)) > 0) { os.write(buffer, 0, count); }//关闭流os.flush();os.close();is.close();}/*** * @param file 指定的文件大小* @param maxFileSize_KB 要对比的值* @return 返回:指定文件与要对比值的差值 .单位KM* @throws Exception*/private  double verFile(File file,int maxFileSize_KB) throws Exception{long fileS = getFileSize(file);double fileSize = 1;return ((double) fileS / 1024) - maxFileSize_KB;}/***  获取指定文件大小 * @param file 指定文件* @return 返回:字节单位的大小* @throws Exception*/private long getFileSize(File file) throws Exception {long size = 0;if (file.exists()) {FileInputStream fis = null;fis = new FileInputStream(file);size = fis.available();} else {size = 0;}return size;}}

MainActivity

package com.myetc.bitmapuse;import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;import com.myetc.bitmapuse.ImageHelp.State;public class MainActivity extends Activity {private Button a;private Context context = this;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);a = new Button(context);a.setText("压缩");setContentView(a);initAction();}Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {super.handleMessage(msg);;a.setText(""+msg.obj);};};private void initAction(){a.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String path = Environment.getExternalStorageDirectory().getPath();//获取手机本地存//储路径,这个位置可以根据需要自己改。ImageHelp m_ImageHelp = new ImageHelp();m_ImageHelp.setImageHelpListen(new ImageHelp.ImageHelpListen() {@Overridepublic void getState(State state, Throwable e) {Message msg =   handler.obtainMessage();switch (state) {case START:System.out.println("保存开始");msg.obj = "保存开始";break;case ING:System.out.println("保存中");msg.obj = "保存中";break;case SUCCESS:msg.obj = "保存成功";break;case ERROR:msg.obj = "保存错误";e.printStackTrace();break;default:msg.obj = "其它";break;}handler.sendMessage(msg);}});m_ImageHelp.resampleImageAndSaveToNewLocation(context, "/mnt/sdcard/aaa/p1.jpg", "sdcard/aaa/test/p000.jpg",0);}});}}

有关图片的压缩,整理一下.有用的COPY相关推荐

  1. 图片批量压缩变小的办法

    手机拍的照片往往尺寸过大,或者时间长了我们需要对电脑的图片进行整理,很多情况下需要对大量图片进行压缩变小.图片批量压缩变小的办法,不知道大家有没有什么好的分享.今天我就分享我的方法,我使用公司安装的的 ...

  2. 图片怎么在线压缩?图片在线压缩方法分享

    通过压缩图片,可以减小图片的大小,从而减少所需的存储空间.这对于在有限存储空间的设备上存储大量照片和视频非常有用.此外,还可以减少在设备之间传输和处理图片所需的时间和精力,从而提高工作的效率.特别是在 ...

  3. android 最全 图片相关知识整理

    android 最全 图片相关知识整理 图片基础知识梳理 图片基础知识梳理(1) - ImageView 的 ScaleType 属性解析 图片基础知识梳理(2) - Bitmap 占用内存分析 图片 ...

  4. 手机中的图片怎么压缩大小?

    手机中的图片怎么压缩大小?我们的手机中都会保存很多的图片,这些图片有些会很大,怎么将手机中的图片压缩变小呢,下面小编就给大家分享一个将手机中的图片压缩变小的简单方法. 第一种方法:在线压缩 1:(首先 ...

  5. ios 上传图片失败 小程序_小程序图片自动压缩配置

    问题 在我现在负责的小程序中,每次ui变更都需要引入新的图片,为了控制小程序体积,都需要先把图片压缩了再放到项目中,但是每次都要手动压缩一次,太麻烦了.所以我想能否在项目加入图片的时候,自动的对加入的 ...

  6. 将图片序列压缩成视频

    原文链接:http://blog.csdn.net/carson2005/article/details/7085480 有些时候,我们确实需要将一个图片序列压缩成视频文件,从而方便观看,或者给别人展 ...

  7. 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( 初始化压缩对象 | 打开文件 | 设置压缩参数 | 写入压缩图像数据 | 完成压缩 | 释放资源 )

    文章目录 一.使用 libjpeg-turbo 压缩图片流程 二.初始化 JPEG 压缩对象 三.打开文件 四.设置压缩参数 五.开始压缩 六.循环写入压缩数据 七.完成图片压缩及收尾 八.libjp ...

  8. 【Android 内存优化】图片文件压缩 ( Android 原生 API 提供的图片压缩功能能 | 图片质量压缩 | 图片尺寸压缩 )

    文章目录 一. 图片压缩 二. 图片文件压缩类型 三. Android 原生 API 提供的质量压缩 四. Android 原生 API 提供的尺寸压缩 一. 图片压缩 图片压缩 : ① 文件压缩 : ...

  9. 图片转svg标注_两个免费网站轻松搞定图片文件压缩转化!

    关注· 点击蓝字,关注我吧 图片压缩 文件转格式 两个免费网站轻松搞定 免费处理图片文字网站 前几天做公号的时候,上传图片遇到了图片过大无法上传的问题.这两个网站可以看做是兄弟俩,今天推荐给大家,省去 ...

最新文章

  1. Atitit.提升 升级类库框架后的api代码兼容性设计指南
  2. 如何为jframe设置于右侧滑轮_如何为电脑设置屏保密码?
  3. 设计案例——点和圆的关系
  4. 常用Git指令常用git命令清单
  5. LOJ#2145. 「SHOI2017」分手是祝愿
  6. 公众号 接收规则 消息_微信公众平台 发送模板消息(Java接口开发)
  7. AJAX设置光标离开自动提交,Ajax自动提交和刷新页面
  8. View事件机制分析
  9. 在 iPhone 中设置 APP 限制使用时间的方法
  10. 日常运维管理 常用命令(3)
  11. pandas某一列去重获取唯一值
  12. java数组验证哥德巴赫猜想_java 验证哥德巴赫猜想
  13. 数值分析(11):常微分方程的数值解法之Euler法
  14. 20个常用模拟电路(嵌入式硬件篇)
  15. 使用官网支持工具制作富士施乐打印机一键安装的程序
  16. CentOS7中Docker安装mysql主从复制、日常排错
  17. 给定三角形三个顶点的坐标,如何求三角形的外心的坐标呢?
  18. matlab hist 横坐标,matlab中hist函数的用法_matlab中hist函数 将EXCEL 中的日期 时间 导入到MATLAB坐标轴中...
  19. Quartz 是什么?一文带你入坑
  20. cyp740703 一个女人的自白

热门文章

  1. 2021端午大厂员工福利一览,网友:大厂爽啊。。。
  2. yota3墨水屏设置_【YotaPhone2 手机使用总结】墨水屏|操作|桌面投射|第三方_摘要频道_什么值得买...
  3. GRE E-rater Analysis
  4. 使用teensy 2.0++ 开发板模拟U盘
  5. aplus翻译_promise/A+规范翻译以及手写实现
  6. .Net Core通过NPOI在CentOS 7(Docker)环境中导出Excel报错The type initializer for ‘Gdip‘ 的问题
  7. 每天学一点英文:Espresso 20210812
  8. 视频编辑软件中滚动字幕如何能停下来
  9. 图片去水印哪个软件好用?
  10. 高通PC(笔记本电脑)端骁龙850详细参数介绍