Android-图片压缩(二)- 压缩基础

这篇具有很好参考价值的文章主要介绍了Android-图片压缩(二)- 压缩基础。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. Android - 图片压缩(一)- 项目中取图片转bitmap
  2. Android - 图片压缩(二)- 压缩基础
  3. Android - 图片压缩(三)- 剖析鲁班,借鉴参数
  4. Android - 图片压缩(四)- 手撸压缩工具
  5. Android - 图片压缩(五)- 推广使用,开始属于你的工具库
前言:让我们手撸一个图片压缩库,对压缩工具鲁班进行升级改造。
在平常开发当中,我们一般是使用第三方的工具,不仅快,而且上手简单,基本不用我们动脑子,压缩我们用鲁班压缩,加载图片我们用Glide,这两大工具我想在座的基本上都用吧,不过我们要想提升自己,就要搞清楚深一点的东西,这里我将会带着大家做一款压缩工具,功能媲美鲁班压缩,而且还带有鲁班没有的功能,如输出指定格式等,在这个过程中我们要学会如何获取bitmap,第一篇已经罗列了多种从项目中取图片转bitmap,这里就不多说了。当我们拿到bitmap我们要知道的事情还有很多,比如图片的色彩模式,一个像素点大小,什么是色深,位深等。绝对让你有收获,干货满满,冲呀。
 目录
1、图片相关概念
   1.1 ARGB介绍    
  1.2 Bitmap概念
  1.3 色彩模式
  1.4 色深和位深
  1.5 内存中Bitmap的大小
  1.6 系统一般分配的大小
2、图片压缩方式
3、压缩的常见方式
  3.1、质量压缩
  3.2、采样压缩
    3.2.1 临近采样(临近点插值算法)
    3.2.2 双线性采样(双线性内插值算法)
    3.2.3 双线性采样对比邻近采样的优势在于:
4、微信和鲁班压缩对比
 

1、图片相关概念

1.1 ARGB介绍

 
ARGB颜色模型:最常见的颜色模型,设备相关,四种通道,取值均为[0,255],即转化成二进制位0000 0000 ~ 1111 1111。
 
A:Alpha (透明度) R:Red (红) G:Green (绿) B:Blue (蓝)
 

1.2 Bitmap概念

 
Bitmap对象本质是一张图片的内容在手机内存中的表达形式。它将图片的内容看做是由存储数据的有限个像素点组成;每个像素点存储该像素点位置的ARGB值。每个像素点的ARGB值确定下来,这张图片的内容就相应地确定下来了。
 

1.3 色彩模式

Bimap.Config下
  1. ALPHA_8 =>8位(1B)
  2. RGB_565 =>16位(2B)
  3. ARGB_4444 =>16位(2B)
  4. ARGB_8888 =>32比特位(4字节,4B)
  5. RGBA_F16 =>64位(8B)
Bitmap.Config是Bitmap的一个枚举内部类,它表示的就是每个像素点对ARGB通道值的存储方案。取值有以下四种:
 
ALPHA_8:每个像素占8位(1个字节),存储透明度信息,没有颜色信息。
 
RGB_565:没有透明度,R=5,G=6,B=5,,那么一个像素点占5+6+5=16位(2字节),能表示2^16种颜色。
 
ARGB_4444:由4个4位组成,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位 (2字节),能表示2^16种颜色。
 
ARGB_8888:由4个8位组成,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位(4字节),能表示2^24种颜色。
 
注意:
1 byte(字节) = 8bit(位)
1 KB = 1024 byte(字节)
 

1.4 色深和位深

  • 色深:每一个像素点用多少bit来存储ARGB值
  • 位深:每个像素点在计算机中所使用的二进制数值位数叫做位深度,主要用于存储
 

1.5 内存中Bitmap的大小

从网络下载,asset,sd卡取的图片计算公式
分辨率 * 每个像素点的大小(如1080*1920*4B = xxx ) (32/8=4)
从res内不同资源目录下
decodeResource()会经过一次分辨率的转换,再计算大小
新分辨率 = 原图横向分辨率 * (设备的 dpi / 目录对应的 dpi ) * 原图纵向分辨率 * (设备的 dpi / 目录对应的 dpi )。
 

1.6 系统一般分配的大小

maxMemory() 返回Java虚拟机将尝试使用的最大内存量。如果没有固有的限制,则值为Long。将返回MAX_VALUE。
返回:
虚拟机将尝试使用的最大内存量,以字节为单位
 
// 获取应用程序最大可用内存(以字节为单位,/1024/1024=M  华为p20 pro是384M)
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory / 8;
  // 设置图片缓存大小为程序最大可用内存的1/8
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getByteCount();
			}

----------------------其他获取方式--------------------
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
//最大分配内存,单位M
int memoryClass = activityManager.getMemoryClass();
Log.e("memoryclass=",String.valueOf(memoryClass));
//最大分配内存获取方法2
float maxMemory = (float) (Runtime.getRuntime().maxMemory() * 1.0/ (1024 * 1024));
//当前分配的总内存
float totalMemory = (float) (Runtime.getRuntime().totalMemory() * 1.0/ (1024 * 1024));
//剩余内存
float freeMemory = (float) (Runtime.getRuntime().freeMemory() * 1.0/ (1024 * 1024));
Log.e("memoryclass=maxMemory",String.valueOf(maxMemory));
Log.e("memoryclass=totalMemory",String.valueOf(totalMemory));
Log.e("memoryclass=freeMemory",String.valueOf(freeMemory));

2、图片压缩方式

    • 设置图片格式
      • png:无损的压缩图片格式
      • jpeg:有损的压缩图片格式,不能透明设置。
      • webp:同时提供了有损和无损图片格式。无损的格式要比png小26%,有损的比jpeg大25%-30%。
    • 质量压缩
    • 采样率压缩
    • 缩放压缩
      • 减少图片的像素,缩略图
    • JNI调用JPEG库
 
Android目前常用的图片格式有png,jpeg和webp,
 
png:无损压缩图片格式,支持Alpha通道,Android切图素材多采用此格式
 
jpeg:有损压缩图片格式,不支持背景透明,适用于照片等色彩丰富的大图压缩,不适合logo
 
webp:是一种同时提供了有损压缩和无损压缩的图片格式,派生自视频编码格式VP8,从谷歌官网来看,无损webp平均比png小26%,有损的webp平均比jpeg小25%~34%,无损webp支持Alpha通道,有损webp在一定的条件下同样支持,有损webp在Android4.0(API 14)之后支持,无损和透明在Android4.3(API18)之后支持
采用webp能够在保持图片清晰度的情况下,可以有效减小图片所占有的磁盘空间大小
 
Android中Bitmap所占内存大小计算方式:图片长度 x 图片宽度 x 一个像素点占用的字节数
 

3、压缩的常见方式

  • 质量压缩:降低存储体积(不改变内存中Bitmap的大小)
  • 采样压缩:降低图片的尺寸,(当然存储体积和内存占用都会降低)
质量压缩:主要是通过编解码来达到缩小体积。
采样压缩:主要是通过采样率,像素点个数等来达到缩小体积
 

3.1、质量压缩

一般用到Bitmap.compress(Bitmap.CompressFormat.JPEG,quality,outputStream)
 
Bitmap.compress(Bitmap.CompressFormat.JPEG,quality,outputStream)
其中
Bitmap.CompressFormat.JPEG
Bitmap.CompressFormat.PNG  无损,无法再质量压缩?
Bitmap.CompressFormat.WEBP  可优化30%,比JPEG更加省空间

quality:0-100,1最小体积,100 最高质量,体积也是最大
outputStream:  ByteArrayOutputStream 一个输出流,压缩后的流,如果要保存成图片文件,就保存此流

3.2、采样压缩

  • 临近采样(临近点插值算法)
  • 双线性采样(双线性内插值算法)

3.2.1 临近采样(临近点插值算法)

使用了BitmapFactory.options  下的
inSampleSize:采样压缩系数  如果是2,直接缩放宽高为原先 二分之一 (1/2)
该方式比较粗暴,2个像素取一个。宽高都减少了,自然内存也降低了。
------------------------------------------------------------------------------
    public static void ljCom(InputStream open){
        BitmapFactory.Options options = new BitmapFactory.Options();
//或者 inDensity 搭配 inTargetDensity 使用,算法和 inSampleSize 一样
        options.inSampleSize = 2; //设置图片的缩放比例(宽和高) , google推荐用2的倍数:
//        Bitmap bitmap = BitmapFactory.decodeFile("app/src/main/assets/wx.png");
//        Bitmap compress = BitmapFactory.decodeFile("app/src/main/assets/wx.png", options);

        Bitmap mbitmap = BitmapFactory.decodeStream(open, null, options);

        Log.e("双线性采样","----压缩后----》"
                +"\n内存大小》"+mbitmap.getByteCount()
                +"\n宽度》"+mbitmap.getWidth()
                +"\n高度》"+mbitmap.getHeight());

    }

3.2.2 双线性采样(双线性内插值算法)

双线性采样(Bilinear Resampling)在 Android 中的使用方式一般有两种:
Bitmap bitmap = BitmapFactory.decodeFile("xxx.png");
Bitmap compress = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, true);
或者直接使用 matrix 进行缩放

Bitmap bitmap = BitmapFactory.decodeFile("xxx.png");
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
bm = Bitmap.createBitmap(bitmap, 0, 0, bit.getWidth(), bit.getHeight(), matrix, true);
看源码可以知道createScaledBitmap函数最终也是使用第二种方式的matrix进行缩放,双线性采样使用的是双线性內插值算法,这个算法不像邻近点插值算法一样,直接粗暴的选择一个像素,而是参考了源像素相应位置周围2x2个点的值,根据相对位置取对应的权重,经过计算之后得到目标图像。
 
双线性内插值算法在图像的缩放处理中具有抗锯齿功能, 是最简单和常见的图像缩放算法,当对相邻2x2个像素点采用双线性內插值算法时,所得表面在邻域处是吻合的,但斜率不吻合,并且双线性内插值算法的平滑作用可能使得图像的细节产生退化,这种现象在上采样时尤其明显。
 
filter:
当进行的不只是平移变换时,filter参数为true可以进行滤波处理,有助于改善新图像质量;flase时,计算机不做过滤处理。
使用方式
/**
 * 双线性采样
 * */
public static void sxxCon(Bitmap bitmap){
    Log.e("双线性采样","----压缩前----》"
            +"\n内存大小》"+bitmap.getByteCount()
            +"\n原图宽度》"+bitmap.getWidth()
            +"\n原图高度》"+bitmap.getHeight());
    //等比例缩放压缩
    Bitmap mbitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, true);
    Log.e("双线性采样","----压缩后----》"
            +"\n内存大小》"+mbitmap.getByteCount()
            +"\n宽度》"+mbitmap.getWidth()
            +"\n高度》"+mbitmap.getHeight());
}
/**
 * 双线性采样
 * */
public static void sxxCon2(Context context,Bitmap bitmap){
    Log.e("双线性采样","----压缩前----》"
            +"\n内存大小》"+bitmap.getByteCount()
            +"\n宽度》"+bitmap.getWidth()
            +"\n高度》"+bitmap.getHeight());
    Matrix matrix = new Matrix();
    matrix.setScale(0.6f, 0.6f);
    Bitmap mbitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    Log.e("双线性采样","----压缩后----》\n"
            +"\n内存大小》"+mbitmap.getByteCount()
            +"\n宽度》"+mbitmap.getWidth()
            +"\n高度》"+mbitmap.getHeight());
    saveBitmapAsPng2(context,mbitmap,"aaq");
}

3.2.3 双线性采样对比邻近采样的优势在于:

 
它的系数可以是小数,而不一定是整数,在某些压缩限制下,效果尤为明显
处理文字比较多的图片在展示效果上的差别,双线性采样效果要更好
 

4、微信和鲁班压缩对比

 
微信
LuBan
1
采样率压缩
 
2
进行宽高的等比压缩(微信对原图和缩略图限制了最大长宽或者最小长宽)
进行宽高的等比压缩
3
对图片的质量进行压缩(一般75或者70)
应该说的是quality=75
对图片的质量进行压缩
4
采用webP的格式
 
 
 
 
 

文章来源地址https://www.toymoban.com/news/detail-432736.html

到了这里,关于Android-图片压缩(二)- 压缩基础的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android-图片压缩详解:原理、方法与实践

    在Android应用开发中,处理图片是一个非常常见的需求。然而,大尺寸和高质量的图片可能会占用大量内存,导致应用程序性能下降,甚至引发OOM(Out of Memory)错误。因此,对图片进行合适的压缩是非常重要的。本文将详细介绍Android图片压缩的原理、方法和实践。 图片压缩的

    2024年02月16日
    浏览(22)
  • UEditorPlus v3.3.0 图片上传压缩重构,UI优化,升级基础组件

    UEditor是由百度开发的所见即所得的开源富文本编辑器,基于MIT开源协议,该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。 UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器,主要做了样式的定制,更符合现代浏览器的审美。 在开发过程中解决了部

    2024年02月14日
    浏览(37)
  • 【Android开发基础】说说模块设计(下拉刷新、图片查看、布局设计)

    描述:设计一个简单说说功能模块 需求: 1、能够下拉刷新,更新数据 2、一条说说里允许包含多张图片,图片能够放大查看 难度:初级 知识点: 1、Swiperefreshlayout 2、适配器Adapter 3、对话框Dialog 4、文字图标Icon 1、下拉刷新 思路        使用官方提供的解决方案SwipeRefre

    2024年02月08日
    浏览(27)
  • Android修行手册-基础优化系列图片篇,ios音视频面试内容

    图片款=(480/480)*400=400 占用内存为300*400*4=480000 那么它占用内存为什么是变化的? Android会先解析图片文件本身的数据格式,然后还原成Bitmap对象,Bitmap的大小就跟上面的计算方式相关联。 再举例1080*452的png图片,图片占用存储空间大小为56kb,内存如图: 上图一目了然,不

    2024年04月27日
    浏览(36)
  • 如何压缩jpg图片kb大小?在线图片压缩工具推荐

    如果在编辑文稿的时候,使用太多这些高分辨率的图片,文稿的体积也会变得很大,这样子不仅打开文稿会比较耗时,传输文稿的时候,也不太方便,这时候就需要图片压缩一下,那么如何实现jpg压缩(https://www.yasuotu.com/jpg)呢?下面推荐一个压缩jpg工具,一起来了解一下吧

    2023年04月08日
    浏览(64)
  • 怎么用手机压缩图片?教给大家三种手机压缩图片方法

    如何使用手机把图片的内存进行压缩呢?大家在使用照片的时候,如果照片的内存太大,不仅会占用手机的内存,也会影响一些网站上传图片的操作,因为图片内存太大很多都是上传不了的,为了解决这一问题我们可以将图片进行压缩。今天给大家分享三种手机就能压缩图片

    2024年02月08日
    浏览(32)
  • python压缩图片--指定压缩大小且保真压缩

    循环降低图片质量quality 直至图片质量大小符合目标质量后退出循环 pillow处理后和原图片的对比 使用pillow压缩的图片不单止大小质量没达标而且处理后的图片失真不忍直视。 opencv处理后和原图片的对比 想用python压缩图片然后网上搜,搜索结果90%都是python使用pillow的压缩。最

    2024年02月11日
    浏览(33)
  • 图片怎么压缩到200K以内,这3个图片压缩方法,简单有效

    你没有遇到过上传图片到网站的时候,图片太大不能上传的情况?还有,许多报名照片要求小于200K,可是照片超过这个大小,应该如何压缩呢?下面我给大家带来3个图片压缩的方法,既能快速压缩图片大小,又保存画质清晰。 方法一:用画图工具压缩 1、对着需要压缩的图

    2023年04月24日
    浏览(59)
  • uniapp 上传图片时压缩图片

    提示:这里简述项目相关背景: 最近用uniapp做一个上传图片,要把图片大小压缩到200kb,然后传给后端 image-conversion:一个简单易用的JS图像转换工具,可以指定大小以压缩图像 npm i image-conversion --save const imageConversion = require(“@/components/image-conversion”);

    2024年02月12日
    浏览(26)
  • 【鸿蒙NEXT】图片选择和图片压缩

    2024年04月10日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包