博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android图片采样缩放
阅读量:6235 次
发布时间:2019-06-22

本文共 4360 字,大约阅读时间需要 14 分钟。

为什么要对Android中的图片进行采样缩放呢?

是为了更加高效的加载Bitmap。假设通过imageView来显示图片,很多时候ImageView并没有图片的原始尺寸那么大,这时候把整张图片加载进来后再设给ImageView是没有必要的,因为ImagView并没有办法显示原始的图片。

所以我们可以使用BitmapFactory.Options按照一定的采样率加载缩小后的图片,将缩小后的图片在ImageView中显示,这样就能降低内存占用,在一定程度上避免OOM,提高bitma加载时候的性能。

 

BitmapFactory有一个参数:inSampleSize(采样率)。

inSampleSize为1,那么采样后图片大小等于原始图片大小。

 

inSampleSize为2,那么采样后图片宽高均为原始图片的1/2,像素为原图的1/4,占有的内存大小为原图的1/4。

 

例如:一张的图片像素为1024*1024,储存格式为ARGB8888格式储存,那么它占有内存1024*1024*4=4M,用采样率为2采样后内存占用为512*512*4=1M。

总结:inSampleSize是必须大于1的整数才有效果,小与1就相当于1,并且同时作用于宽高,所以缩放后的图片大小以采样率的2次方形式递减.根据最新的官方文档,inSampleSize的取值应该总是为2的指数,若给系统的inSampleSize不为2的指数,那么系统会向下取整并且选择一个最接近2的指数来代替,不过经过验证,这个结论并不是在所有的Android版本上都成立。

 

 那么我们如何获取采样率呢?

1、将BitmapFactory.Option的inJustDecodeBound参数设为true,加载图片,这个时候图片并没有加载进内存,仅仅是去解析图片原始宽高信息而已。

2、从BitmapFactory.Option取出图片的原始宽高信息,对应于outWidth,outHeight参数。

3、根据采样率的规则和目标原始View的所需大小计算出采样率inSampleSize。

4、将BitmapFactory.Option的inJustDecodeBound参数设为false,重新加载图片,这时候图片才真正被载进内存。

 

以下提供一份代码模板:package com.example.chatting.chatting.utils;

import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.util.DisplayMetrics;import android.view.ViewGroup.LayoutParams;import android.widget.ImageView;public class ImagesTool {    /**     * 根据ImageView的大小压缩图片     * @param path     * @param imageView     * @return     */    public static Bitmap decodeSampledBitmapFromPath(String path,ImageView imageView)    {        Options options = new Options();        options.inJustDecodeBounds=true;        BitmapFactory.decodeFile(path,options);                ImageSize imageSize=getImageViewSize(imageView); //获取图片大小,ImageSize是封装着ImageView大小的类         //计算采样率        options.inSampleSize=caculateInSampleSize(options,imageSize.width,imageSize.height);                options.inJustDecodeBounds=false;        Bitmap bitmap=BitmapFactory.decodeFile(path, options);        return bitmap;    }    //计算采样率    public static int caculateInSampleSize(Options options,ImageView imageView)    {        ImageSize imageSize=getImageViewSize(imageView);        int inSampleSize=caculateInSampleSize(options, imageSize.width,imageSize.height);        return inSampleSize;    }    /**     * 根据具体的大小要求解析图片     * @param path     * @param reqWidth     * @param reqHeight     * @return     */    public static Bitmap decodeSampledBitmapFromPath(String path,int reqWidth, int reqHeight)    {        Options options = new Options();        options.inJustDecodeBounds=true;        BitmapFactory.decodeFile(path,options);        //计算采样率        options.inSampleSize=caculateInSampleSize(options,reqWidth,reqHeight);                options.inJustDecodeBounds=false;        Bitmap bitmap=BitmapFactory.decodeFile(path, options);        return bitmap;            }    //计算采样率    private static int caculateInSampleSize(Options options, int reqWidth, int reqHeight)     {                int width=options.outWidth; //原始图片宽        int height=options.outHeight; //原始图片高                int inSampleSize=1; //采样率        if(width>reqWidth || height>reqHeight) //原始的宽比目标宽大,或者原始高比目标高大        {            int widthRadio=Math.round(width *1.0f/reqWidth);            int heightRadio = Math.round(height * 1.0f / reqHeight);            inSampleSize = Math.max(widthRadio, heightRadio);        }        return inSampleSize;    }    //获取ImageView的大小    protected static ImageSize getImageViewSize(ImageView imageView)     {        ImageSize imageSize = new ImageSize();        DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();        LayoutParams lp = imageView.getLayoutParams();        int width = imageView.getWidth();        if (width <= 0) {            width = lp.width;        }        if (width <= 0) {            width = imageView.getMaxWidth();        }        if (width <= 0) {            width = metrics.widthPixels;        }        int height = imageView.getHeight();        if (height <= 0) {            height = lp.height;        }        if (height <= 0) {            height = imageView.getMaxHeight();        }        if (height <= 0) {            height = metrics.heightPixels;        }        imageSize.width = width;        imageSize.height = height;        return imageSize;    }    //ImageView大小的封装类    private static class ImageSize    {        int width;        int height;    }}

 

转载于:https://www.cnblogs.com/tangZH/p/7833010.html

你可能感兴趣的文章
asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?...
查看>>
用VMWARE模拟打造通用批量分发安装系统
查看>>
Python 字符串、列表、元组、索引、切片
查看>>
JAVA实现显示指定类型的文件的例子
查看>>
rm -rfi 防止误删除数据
查看>>
Java项目打war包的方法
查看>>
ubuntu server 10.4 下LVS-DR+heartbeat +Ldirectord实现web服务高可性负载均衡实验
查看>>
流媒体服务器支持flv格式文件
查看>>
(4)制作windows 2003自动安装盘-集成补丁/Raid及硬件驱动
查看>>
MDeamon如何限制进出邮件大小
查看>>
为C# as 类型转换及Assembly.LoadFrom埋坑!
查看>>
word的问题
查看>>
MDaemon邮件报表统计插件——MailDetective
查看>>
为何有着良好设计的系统代码反而不容易看懂?
查看>>
[Ajax]ajax入门
查看>>
什么是BPOS
查看>>
JSP中的四种属性范围(重点)
查看>>
Ubuntu init启动流程分析浅析
查看>>
linux之df命令
查看>>
HDOJ 1303 Doubles(简单题)
查看>>