当前位置: 首页 > news >正文

Android图片采样缩放

为什么要对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

相关文章:

  • dig一些常用例子
  • 【52ABP实战教程】0.1-- Devops如何用VSTS持续集成到Github仓库!
  • nginx 另一WAF方式
  • 修改Linux的22端口几种方法
  • 再谈谈火车票系统
  • 模式--创建型
  • Just for fun——迅速写完快速排序
  • 十六进制之间的转换(二进制、八进制、十六进制、十进制)
  • php7.1.1一键安装/配置文件简单优化
  • Office 365中管理员角色介绍-进阶篇
  • SQL Server-表表达式基础
  • Oracle 11g RAC 故障之--Instance 启动失败
  • Nginx基于用户名和密码的访问控制
  • VS2005和ASP.NET2.0中使用强类型数据
  • HTML 简介
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【Leetcode】104. 二叉树的最大深度
  • CentOS从零开始部署Nodejs项目
  • create-react-app做的留言板
  • ES10 特性的完整指南
  • JAVA SE 6 GC调优笔记
  • Js基础知识(一) - 变量
  • Linux快速复制或删除大量小文件
  • Lucene解析 - 基本概念
  • node和express搭建代理服务器(源码)
  • session共享问题解决方案
  • spring boot下thymeleaf全局静态变量配置
  • Vue官网教程学习过程中值得记录的一些事情
  • windows下如何用phpstorm同步测试服务器
  • 多线程事务回滚
  • 检测对象或数组
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 前端攻城师
  • 王永庆:技术创新改变教育未来
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 带你开发类似Pokemon Go的AR游戏
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #微信小程序:微信小程序常见的配置传旨
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (3)STL算法之搜索
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (剑指Offer)面试题34:丑数
  • **python多态
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .net解析传过来的xml_DOM4J解析XML文件
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • @font-face 用字体画图标
  • @vue/cli脚手架
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [20171106]配置客户端连接注意.txt
  • [22]. 括号生成
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured