Android图片压缩(质量压缩和尺寸压缩)

在做项目中遇到一个头疼的问题,读取本地图片时,由于图片太大,奔溃,对于我这种456M内存的破手机哪里受得了几M的照片
我要总结的有这么几点:
1、尺寸压缩和质量压缩
2、处理过的图片存储本地和sqlite数据库
先看1:图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,
                  质量压缩:它其实只能实现对file的影响,,你可以把一个file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是                                            被压缩过的,但是中间的bitmap并没有被压缩(或者说几乎没有被压缩,我不确定),因为bigmap在内存中的大小是按像素                                            计算的,也就是width * height,对于质量压缩,并不会改变图片的像素,所以就算质量被压缩了,但是bitmap在内存的占有率                                        还是没变小,但你做成file时,它确实变小了。
                     尺寸压缩:

                                   而尺寸压缩由于是减小了图片的像素,所以它直接对bitmap产生了影响,当然最终的file也是相对的变小了;
                                   尺寸压缩对分辨率的处理    接对bitmap产生了影响,当然最终的file也是相对的变小,影响内存。
上诉就是对这两种压缩方式理解,看看代码怎么实现的吧:
1、首先:点击你某个控件进入相册界面,我用的是一个图片按钮
circleImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent = new Intent();// 开启Pictures画面Type设定为image
                intent.setType("image/*");//
                intent.setAction(Intent.ACTION_GET_CONTENT);
                /*
                 * 得到新打开Activity关闭后返回的数据,你需要使用系统提供的
                 * startActivityForResult(Intent intent,int
                 * requestCode)方法打开新的Activity
                 */
                startActivityForResult(intent, 1);// 取得相片后返回本画面
            }

});

2、点击图片将会调用onActivityResult这个方法,尺寸压缩就这个方法里面实现吧!
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {// 选取图片的返回值
            if (resultCode == RESULT_OK) {
                Uri uri = data.getData();
                Cursor cursor = getContentResolver().query(uri, nullnull,
                        nullnull);
                cursor.moveToFirst();// 指向查询结果的第一个位置
                String imgPath1 = cursor.getString(1); // 图片文件路径
                String imgSize = cursor.getString(2); // 图片大小   
                String imgName = cursor.getString(3); // 图片文件名   
                BitmapFactory.Options options = new BitmapFactory.Options();
        
                // 此时把options.inJustDecodeBounds 设回true,即只读边不读内容
                options.inJustDecodeBounds = true;
                // 默认是Bitmap.Config.ARGB_8888
                options.inPreferredConfig = Bitmap.Config.RGB_565
                try {
                //此时不会把图片读入内存,只会获取图片宽高等信息
                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                .openInputStream(uri), null, options);
                //上面一句和下面的类似
                //Bitmap bitmap = BitmapFactory.decodeFile(imgPath,options);
                int heitht = options.outHeight;
                // 根据需要设置压缩比例
                int size = heitht / 800;
                if (size <= 0) {
                size = 2;
                }
                   /*inSampleSize表示缩略图大小为原始图片大小的几分之一,
                      即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,
                      图片大小就为原始大小的1/4*/
                options.inSampleSize = size;
                // 设置options.inJustDecodeBounds重新设置为false
                options.inPurgeable = true;// 同时设置才会有效  
                options.inInputShareable = true;//。当系统内存不够时候图片自动被回收  
                options.inJustDecodeBounds = false;
                //此时图片会按比例压缩后被载入内存中
                bitmap = BitmapFactory.decodeStream(getContentResolver()
                .openInputStream(uri), null, options);
                SaveSD.saveBitmap(imgName,bitmap);//saveBitmap这个是我定义保存到SDcard中的方法
                circleImageView.setImageBitmap(bitmap);
                imgPath="/sdcard/"+imgName;
                } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                }
            }
        }
        super.onActivityResult(requestCode, resultCode, data);

}

经过以上的压缩,减少了对内存的消耗,可以显示出,你想要的照片高清的照片咯。
上面讲的是尺寸压缩主要是影响内存,现在讲的是质量压缩,我们把这个过程放在保存的方法中吧。
质量压缩1,保存到sd卡。保存的时候进行质量压缩,将几M的照片,变为几指定大小的图片
public class SaveSD {
    /**
     * 保存图片到指定文件夹,将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,
     * 
     * @param imgName
     *            图片名称 bitmap 处理图片对象
     * 
     * 
     * */
    public static void saveBitmap(String imgName, Bitmap bitmap) {
        String sdpath = "/sdcard/";
        
        File file = new File(sdpath, imgName);
        if (file.exists()) {
            file.delete();
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        /* options表示 如果不压缩是100,表示压缩率为0。如果是70,就表示压缩率是70,表示压缩30%; */
        int options = 100;
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        while (baos.toByteArray().length / 1024 > 500) {
            // 循环判断如果压缩后图片是否大于500kb继续压缩
            baos.reset();
            options -= 10;
            // 这里压缩options%,把压缩后的数据存放到baos中
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
        }
        try {
            FileOutputStream out = new FileOutputStream(file);
            out.write(baos.toByteArray());
            out.flush();
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
质量压缩2,将头像保存到sqlite数据库,在实例中是是字节,就是将图片转化成字节存入数据库
public class Person implements Serializable{
    private int id;
    private String call;
    private String name;
    private String sexy;
    private String age;

private byte[] image;  .......

在看看创建数据库时,Image是BLOB形式:
/**
     * 数据库第一次创建时回调此方法. 初始化一些表
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        // 操作数据库
        String sql = "create table person(id integer primary key,call varchar(20), " +
                "name varchar(20),sexy varchar(20),age varchar(20),image BLOB);";
        db.execSQL(sql);

}

对bitmap进行质量压缩,并将bitmap转化成字节形式
public class BitmapToByte {
    /**
     * 保存图片到指定文件夹,将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,
     * 
     * @param imgName
     *            图片名称 bitmap 处理图片对象
     * 
     * 
     * */
    public static byte[] saveBitmap(Bitmap bitmap) {
    
        int size=bitmap.getWidth()*bitmap.getHeight()*4;
        //创建一个字节数组输出流,流的大小为size
        ByteArrayOutputStream baos=new ByteArrayOutputStream(size);
        //设置位图的压缩格式,质量为100%,并放入字节数组输出流中
        int options = 100;
        /* options表示 如果不压缩是100,表示压缩率为0。如果是70,就表示压缩率是70,表示压缩30%; */
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        while (baos.toByteArray().length / 1024 > 500) {
            // 循环判断如果压缩后图片是否大于500kb继续压缩
            baos.reset();
            options -= 10;
            // 这里压缩options%,把压缩后的数据存放到baos中
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
        }
        //将字节数组输出流转化为字节数组byte[]
        
        byte[] imagedata=baos.toByteArray();
        return imagedata;
   
    }
}

最后只要得到这个imagedata执行插入语句即可
    personDao = new PersonDao(NewMemberActivity.this);// 该对象可以调用操作数据库方法
                
                person = new Person(sCall, sName, sexy, age, imagedata);// 初始化对象数据,imagedata

personDao.insert(person);// 将对象person插入到数据库

由于时间有限,说得不是很好,见谅啊

android中bitmap压缩的几种方法详解相关推荐

  1. android中bitmap压缩的几种方法的解读

    目录 1.质量压缩法 2.采样率压缩法 3.缩放法 4.RGB_565法 最近在研究微信的sdk,在缩略图这遇到了一点问题. 微信的缩略图要求是不大于32k,这就需要对我的图片进行压缩.试了几种方法, ...

  2. 站长在线Python精讲:在Python中格式化字符串的两种方法详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中格式化字符串的两种方法详解>.本知识点主要内容有:使用%操作符格式化字符串和使用format()方法格式化字 ...

  3. android datepicker使用方法,android中DatePicker和TimePicker的使用方法详解

    本文以实例讲述了android中DatePicker和TimePicker的使用方法,具体步骤如下: 下面是实现具体功能的代码,其中main.xml代码为: android:layout_width= ...

  4. Android之bitmap压缩的几种方法的解读

    转载:http://blog.csdn.net/chzphoenix/article/details/30242315?utm_source=tuicool&utm_medium=referr ...

  5. Qt中线程同步的几种方法详解

    1.QMutex类 QMutex类就像一把锁,在互斥量以前上锁(QMutex::lock()),而后在使用完互斥量以后解锁(QMutex::unlock()).好比下面的代码:函数 void some ...

  6. android获取颜色资源,Android中获取颜色的几种方法

    Android中获取颜色的几种方法: 通过android封装好的Color类中的常量 public static final int BLACK = 0xFF000000; public static ...

  7. android listview ontouchlistener,Android ListView监听滑动事件的方法(详解)

    ListView的主要有两种滑动事件监听方法,OnTouchListener和OnScrollListener 1.OnTouchListener OnTouchListener方法来自View中的监 ...

  8. java 窗体添加背景图片_Java Swing实现窗体添加背景图片的2种方法详解

    本文实例讲述了java Swing实现窗体添加背景图片的2种方法.分享给大家供大家参考,具体如下: 在美化程序时,常常需要在窗体上添加背景图片.通过搜索和测试,发现了2种有效方式.下面分别介绍. 1. ...

  9. python 命令-python解析命令行参数的三种方法详解

    这篇文章主要介绍了python解析命令行参数的三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python解析命令行参数主要有三种方法: ...

最新文章

  1. 使用redisson时关于订阅数的问题
  2. OCCI读写Oracle Spatial的SDO_Geometry
  3. 计算机怎么模拟人,计算机能不能模拟人的思维?
  4. PhpStorm 对 AngularJS 的支持
  5. Win2003 + SQL 2005 做数据库集群总结(虚拟机)
  6. 有条件了!筛选,MySQL条件查询SELECT-WHERE
  7. PHP学习——定界符格式引起的错误
  8. 计算机有必要报英语四级吗,我已工作了,现在有必要去考英语四级吗?还是 – 手机爱问...
  9. 9.jsonp的实现原理
  10. 音视频基础概念与流程
  11. 最新Maven安装教程(详细)
  12. 游戏开发者,游戏开发教程
  13. 解决布局点击事件穿透的问题
  14. 干货|关于云计算认证升级内容
  15. c++ vs2015 播放音乐_三星s20都取消了耳机孔,1k-2k的播放器会成为直推党新选择吗?...
  16. 问:舵机可以作为智能小车的驱动轮吗
  17. 阻塞队列(一):ArrayBlockingQueue
  18. vue删除图片同时删除本地文件_删除图片数据时同时删除图片文件夹里面的相应图片文件的方法...
  19. PCM开发板模块实验指导--有刷直流马达正反转实验
  20. 看板和scrum_从Scrum到看板

热门文章

  1. 什么是render函数?什么时候会用到render函数?
  2. 【C语言循环结构题】迭代法求平方根
  3. eclipse启动慢解决方法
  4. 烂泥:Domino8.5服务器迁移方案
  5. css层叠样式表、基本选择器
  6. c语言第七章函数实验总结,第六章 实验报告 (函数与宏定义)
  7. 日记侠:你真的想知道引流的方法吗?
  8. BPSK码元速率与带宽的关系
  9. 网上收集的几个花指令
  10. Java常用设计模式-策略模式