关于移动端:高性能图片优化方案
作者:愛攝影的新胖 | 来源:互联网 | 2023-05-19 04:39
目录介绍01.图片根底概念介绍1.1图片占用内存介绍1.2加载网络图片流程1.3三方库加载图片逻辑1.4从网络间接拉取图片1.5加载图片的流程1.6Bitmap能间接存
目录介绍
-
01.图片根底概念介绍
- 1.1 图片占用内存介绍
- 1.2 加载网络图片流程
- 1.3 三方库加载图片逻辑
- 1.4 从网络间接拉取图片
- 1.5 加载图片的流程
- 1.6 Bitmap能间接存储吗
- 1.7 Bitmap创立流程
- 1.8 图片框架如何设计
-
02.图片内存计算形式
- 2.1 如何计算占用内存
- 2.2 下面计算内存对吗
- 2.3 一个像素占用内存
- 2.4 应用API获取内存
- 2.5 影响Bitmap内存因素
- 2.6 加载xhdpi和xxhdpi图片
- 2.7 图片一些注意事项
-
03.大图的内存优化
- 3.1 常见图片压缩
- 3.2 图片尺寸压缩
- 3.3 图片品质压缩
- 3.4 双线性采样压缩
- 3.5 高清图分片加载
- 3.6 图片综合压缩
-
04.色调格局及内存优化
- 4.1 RGB色彩品种
- 4.2 ARGB色调模式
- 4.3 扭转色调格局优化
-
05.缓存的应用实际优化
- 5.1 Lru内存缓存
- 5.2 Lru内存注意事项
- 5.3 应用Lru磁盘缓存
-
06.不同版本对Bitmap治理
- 6.1 演变过程
- 6.2 治理Bitmap内存
- 6.3 进步Bitmap复用
-
07.图片其余方面优化
- 7.1 缩小PNG图片的应用
- 7.2 控件切割圆角优化
- 7.3 如何给图片置灰色
- 7.4 如何解决图片旋转呢
- 7.5 保留图片且刷相册
- 7.6 对立图片域名优化
- 7.7 优化H5图片加载
- 7.8 优化图片暗影成果
- 7.9 图片资源的压缩
01.图片根底概念介绍
1.1 图片占用内存介绍
1.2 加载网络图片流程
1.3 三方库加载图片逻辑
1.4 从网络间接拉取图片
-
间接通过网络申请将网络图片转化成bitmap
- 在这将采纳最原生的网络申请形式HttpURLConnection形式进行图片获取。
- 通过测试,申请8张图片,耗时毫秒值174。个别是通过get申请拉取图片的。这种办法应该是最根底的网络申请,大家也能够回顾一下,个别开发中很少用这种形式加载图片。具体能够看:ImageToolLib
-
如何加载一个图片呢?
- 能够看看BitmapFactory类为咱们提供了四类办法来加载Bitmap:decodeFile、decodeResource、decodeStream、decodeByteArray;也就是说Bitmap,Drawable,InputStream,Byte[] 之间是能够进行转换。
1.5 加载图片的流程
-
搞清楚一个图片概念
- 在电脑上看到的 png 格局或者 jpg 格局的图片,png(jpg) 只是这张图片的容器。是通过绝对应的压缩算法将原图每个像素点信息转换用另一种数据格式示意。
-
加载图片显示到手机
- 通过代码,将这张图片加载进内存时,会先解析(也就是解码操作)图片文件自身的数据格式,而后还原为位图,也就是 Bitmap 对象。
-
图片大小vs图片内存大小
- 一张 png 或者 jpg 格局的图片大小,跟这张图片加载进内存所占用的大小齐全是两回事。
1.6 Bitmap能间接存储吗
-
Bitmap根底概念
- Bitmap对象实质是一张图片的内容在手机内存中的表达形式。它将图片的内容看做是由存储数据的无限个像素点组成;每个像素点存储该像素点地位的ARGB值。每个像素点的ARGB值确定下来,这张图片的内容就相应地确定下来了。
-
Bitmap实质上不能间接存储
- 为什么?bitmap是一个对象,如果要存储老本地能够查看的图片文件,则必须对bitmap进行编码,而后通过io流写到本地file文件上。
1.7 Bitmap创立流程
-
对于图片OOM,能够发现一个景象。
- heapsize(虚拟机的内存配置)越大越不容易 OOM,Android8.0 及之后的版本更不容易 OOM,这个该如何了解呢?
-
Bitmap对象内存的变动:
- 在 Android 8.0 之前,Bitmap 像素占用的内存是在 Java heap 中调配的;8.0 及之后,Bitmap 像素占用的内存调配到了 Native Heap。
- 因为 Native heap 的内存调配下限很大,32 位利用的可用内存在 3~4G,64 位上更大,虚拟内存简直很难耗尽,所以揣测 OOM 时 Java heap 中占用内存较多的对象是 Bitmap” 成立的状况下,利用更不容易 OOM。
-
搞清楚Bitmap对象内存调配
- Bitmap 的构造方法是不公开的,在应用 Bitmap 的时候,个别都是通过 Bitmap、BitmapFactory 提供的静态方法来创立 Bitmap 实例。
- 以 Bitmap.createBitmap 阐明了 Bitmap 对象的次要创立过程剖析,能够看到 Java Bitmap 对象是在 Native 层通过 NewObject 创立的。
- allocateJavaPixelRef,是 8.0 之前版本为 Bitmap 像素从 Java heap 申请内存。其外围原理是Bitmap 的像素是保留在 Java 堆上。
- allocateHeapBitmap,是 8.0 版本为 Bitmap 像素从 Native heap 申请内存。其外围原理次要是通过 calloc 为 Bitmap 的像素分配内存,这个调配就在 Native 堆上。
- 更多具体内容能够看:Bitmap对象内存调配
1.8 图片框架如何设计
-
大多数图片框架加载流程
- 概括来说,图片加载蕴含封装,解析,下载,解码,变换,缓存,显示等操作。
-
图片框架是如何设计的
- 封装参数:从指定起源,到输入后果,两头可能经验很多流程,所以第一件事就是封装参数,这些参数会贯通整个过程;
- 解析门路:图片的起源有多种,格局也不尽相同,须要规范化;比方glide能够加载file,io,id,网络等各种图片资源
- 读取缓存:为了缩小计算,通常都会做缓存;同样的申请,从缓存中取图片(Bitmap)即可;
- 查找文件/下载文件:如果是本地的文件,间接解码即可;如果是网络图片,须要先下载;比方glide这块是发动一个申请
- 解码:这一步是整个过程中最简单的步骤之一,有不少细节;比方glide中解析图片数据源,旋转方向,图片头等信息
- 变换和压缩:解码出Bitmap之后,可能还须要做一些变换处理(圆角,滤镜等),还要做图片压缩;
- 缓存:失去最终bitmap之后,能够缓存起来,以便下次申请时间接取后果;比方glide用到三级缓存
- 显示:显示后果,可能须要做些动画(淡入动画,crossFade等);比方glide设置显示的时候能够增加动画成果
02.图片内存计算形式
2.1 如何计算占用内存
- 如果图片要显示下Android设施上,ImageView最终是要加载Bitmap对象的,就要思考单个Bitmap对象的内存占用了,如何计算一张图片的加载到内存的占用呢?其实就是所有像素的内存占用总和:
- bitmap内存大小 = 图片长度 x 图片宽度 x 单位像素占用的字节数
- 起决定因素就是最初那个参数了,Bitmap常见有2种编码方式:ARGB_8888和RGB_565,ARGB_8888每个像素点4个byte,RGB_565是2个byte,个别都采纳ARGB_8888这种。那么常见的1080*1920的图片内存占用就是:1920 x 1080 x 4 = 7.9M
2.2 下面计算内存对吗
2.3 一个像素占用内存
2.4 应用API获取内存
2.5 影响Bitmap内存因素
-
影响Bitmap占用内存的因素:
- 图片最终加载的分辨率;
- 图片的格局(PNG/JPEG/BMP/WebP);
- 图片所寄存的drawable目录;
- 图片属性设置的色调模式;
- 设施的屏幕密度;
2.6 加载xhdpi和xxhdpi图片
2.7 图片一些注意事项
03.大图的内存优化
3.1 常见图片压缩
3.2 图片尺寸压缩
3.2.1 如何了解尺寸压缩
-
通常在大多数状况下,图片的理论大小都比须要出现的尺寸大很多。
- 例如,咱们的原图是一张 2700 1900 像素的照片,加载到内存就须要 19.6M 内存空间,然而,咱们须要把它展现在一个列表页中,组件可展现尺寸为 270 190,这时,咱们实际上只须要一张原图的低分辨率的缩略图即可(与图片显示所对应的 UI 控件匹配),那么实际上 270 * 190 像素的图片,只须要 0.2M 的内存即可。
- 能够看到,优化前后相差了 98 倍,原来显示 1 张,当初能够显示 98 张图片,成果十分显著。
-
既然在对原图缩放能够显著缩小内存大小,那么咱们应该如何操作呢?
- 先加载到内存,再进行操作吗,能够如果先加载到内存,如同也不太对,这样只接占用了 19.6M + 0.2M 2份内存了,而咱们想要的是,在原图不加载到内存中,只接将缩放后的图片加载到内存中,能够实现吗?
-
BitmapFactory 提供了从不同资源创立 Bitmap 的解码办法:
- decodeByteArray()、decodeFile()、decodeResource() 等。然而,这些办法在结构位图的时候会尝试分配内存,也就是它们会导致原图间接加载到内存了,不满足咱们的需要。咱们能够通过 BitmapFactory.Options 设置一些附加的标记,指定解码选项,以此来解决该问题。
- 如何操作呢?答案来了:将 inJustDecodeBounds 属性设置为 true,能够在解码时防止内存的调配,它会返回一个 null 的 Bitmap ,然而能够获取 outWidth、outHeight 和 outMimeType 值。利用该属性,咱们就能够在图片不占用内存的状况下,在图片压缩之前获取图片的尺寸。
-
怎样才能对图片进行压缩呢?
- 通过设置BitmapFactory.Options中inSampleSize的值就能够实现。其计算形式大略就是:计算出理论宽高和指标宽高的比率,而后抉择宽和高中最小的比率作为inSampleSize的值,这样能够保障最终图片的宽和高。
3.2.2 设置BitmapFactory.Options属性
-
大略步骤如下所示
- 要将BitmapFactory.Options的inJustDecodeBounds属性设置为true,解析一次图片。留神这个中央是外围,这个解析图片并没有生成bitmap对象(也就是说没有为它分配内存控件),而仅仅是拿到它的宽低等属性。
- 而后将BitmapFactory.Options连同冀望的宽度和高度一起传递到到calculateInSampleSize办法中,就能够失去适合的inSampleSize值了。这一步会压缩图片。
- 之后再解析一次图片,应用新获取到的inSampleSize值,并把inJustDecodeBounds设置为false,就能够失去压缩后的图片了。此时才正式创立了bitmap对象,因为后面曾经对它压缩了,所以你会发现此时所占内存大小曾经很少了。
-
具体的实现代码
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
final BitmapFactory.Options optiOns= new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// 调用下面定义的办法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// 应用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
-
思考:inJustDecodeBounds这个参数是干什么的?
- 如果设置为true则示意decode函数不会生成bitmap对象,仅是将图像相干的参数填充到option对象里,这样咱们就能够在不生成bitmap而获取到图像的相干参数了。
-
为何设置两次inJustDecodeBounds属性?
- 第一次:设置为true则示意decode函数不会生成bitmap对象,仅是将图像相干的参数填充到option对象里,这样咱们就能够在不生成bitmap而获取到图像的相干参数。
- 第二次:将inJustDecodeBounds设置为false再次调用decode函数时就能生成bitmap了。而此时的bitmap曾经压缩减小很多了,所以加载到内存中并不会导致OOM。
3.3 图片品质压缩
-
在Android中,对图片进行品质压缩,通常咱们的实现形式如下所示:
//quality 为0~100,0示意最小体积,100示意最高品质,对应体积也是最大
bitmap.compress(Bitmap.CompressFormat.JPEG, quality , outputStream);
-
在上述代码中,咱们抉择的压缩格局是CompressFormat.JPEG,除此之外还有两个抉择:
- 其一,CompressFormat.PNG,PNG格局是无损的,它无奈再进行品质压缩,quality这个参数就没有作用了,会被疏忽,所以最初图片保留成的文件大小不会有变动;
- 其二,CompressFormat.WEBP,这个格局是google推出的图片格式,它会比JPEG更加省空间,通过实测大略能够优化30%左右。
-
Android品质压缩逻辑,函数compress通过一连串的java层调用之后,最初来到了一个native函数:
- 具体看:Bitmap.cpp,最初调用了函数encoder->encodeStream(…)编码保留本地。该函数是调用skia引擎来对图片进行编码压缩。
3.4 双线性采样压缩
-
双线性采样(Bilinear Resampling)在 Android 中的应用形式个别有两种:
bm = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, true);
//或者间接应用 matrix 进行缩放
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
bm = Bitmap.createBitmap(bitmap, 0, 0, bit.getWidth(), bit.getHeight(), matrix, true);
-
看源码能够晓得createScaledBitmap函数最终也是应用第二种形式的matrix进行缩放
- 双线性采样应用的是双线性內插值算法,这个算法不像邻近点插值算法一样,间接粗犷的抉择一个像素,而是参考了源像素相应地位四周2×2个点的值,依据绝对地位取对应的权重,通过计算之后失去指标图像。
3.5 高清图分片加载
- 实用场景 : 当一张图片十分大 , 在手机中只须要显示其中一部分内容 , BitmapRegionDecoder 十分有用 。
- 次要作用 : BitmapRegionDecoder 能够从图像中 解码一个矩形区域 。相当于手在滑动的过程中,计算以后显示区域的图片绘制进去。
- 根本应用流程 : 先创立,后解码 。调用 newInstance 办法 , 创立 BitmapRegionDecoder 对象 ;而后调用 decodeRegion 办法 , 获取指定 Rect 矩形区域的解码后的 Bitmap 对象
3.6 图片综合压缩
-
个别状况下图片综合压缩的整体思路如下:
- 第一步进行采样率压缩;
- 第二步进行宽高的等比例压缩(微信对原图和缩略图限度了最大长宽或者最小长宽);
- 第三步就是对图片的品质进行压缩(个别75或者70);
- 第四步就是采纳webP的格局。
-
对于图片压缩的综合案例如下
04.色调格局及内存优化
4.1 RGB色彩品种
-
RGB 色调模式是工业界的一种色彩规范
- 通过对红(R)、绿(G)、蓝(B)三个色彩通道的变动以及它们相互之间的叠加来失去各式各样的色彩的,RGB即是代表红、绿、蓝三个通道的色彩,这个规范简直包含了人类视力所能感知的所有色彩,是使用最广的色彩零碎之一。Android 中,像素的存储形式应用的色调模式正是 RGB 色调模式。
4.2 ARGB色调模式
4.3 扭转色调格局优化
- Android 中有多种 RGB 模式,咱们能够设置不同的格局,来管制图片像素色彩的显示品质和存储空间。
-
Android.graphics.Bitmap 类里有一个外部类 Bitmap.Config 类,它定义了能够在 Android 中应用的几种色调格局:
public enum Config {
ALPHA_8 (1),
RGB_565 (3),
@Deprecated
ARGB_4444 (4),
ARGB_8888 (5),
RGBA_F16 (6),
HARDWARE (7);
}
-
解释一下这几个值别离代表了什么含意?咱们曾经晓得了:A 代表透明度、R 代表红色、G 代表绿色、B 代表蓝色。
- ALPHA_8:示意,只存在 Alpha 通道,没有存储色调值,只含有透明度,每个像素占用 1 个字节的空间。
- RGB_565:示意,R 占用 5 位二进制的地位,G 占用了6位,B 占用了 5 位。每个像素占用 2 个字节空间,并且不蕴含透明度。
- ARGB_4444:示意,A(透明度)、R(红色)、G(绿色)、B(蓝色)4个通道各占用 4 个 bit 位。每个像素占用 2 个字节空间。
- ARGB_8888:示意,A(透明度)、R(红色)、G(绿色)、B(蓝色)4个通道各占用 8 个 bit 位。每个像素占用 4 个字节空间。
- RGBA_F16:示意,每个像素存储在8个字节上。此配置特地适宜广色域和HDR内容。
- HARDWARE:非凡配置,当位图仅存储在图形内存中时。 此配置中的位图始终是不可变的。
-
那么开发中个别抉择哪一种比拟适合呢
- Android 中的图片在加载时,默认的色调格局是 ARGB_8888,也就是每个像素占用 4 个字节空间,一张 2700 1900 像素的照片,加载到内存就须要 19.6M 内存空间(2592 1936 * 4 bytes)。
- 如果图片在 UI 组件中显示时,不须要太高的图片品质,例如显示一张缩略图(不通明图片)等场景,这时,咱们就没必要应用 ARGB_8888 的色调格局了,只须要应用 RGB_565 模式即可满足显示的须要。
- 那么,咱们的优化操作就能够是:
- 将 2700 1900 像素的原图,压缩到原图的低分辨率的缩略图 270 190 像素的图片,这时须要 0.2M 的内存。也就是从 19.6M内存,压缩为 0.2 M内存。
- 咱们还能够进一步优化色调格局,由 ARGB_8888 改为 RGB_565 模式,这时,指标图片须要的内存就变为 270 190 2 = 0.1M 了。图片内存空间又减小了一倍。
05.缓存的应用实际优化
5.1 Lru内存缓存
- LruCache 类特地适宜用来缓存 Bitmap,它应用一个强援用的 LinkedHashMap 保留最近援用的对象,并且在缓存超出设定大小时,删除最近起码应用的对象。
-
给 LruCache 确定一个适合的缓存大小十分重要,咱们须要思考几个因素:
- 利用残余多少可用内存?
- 须要有多少张图片同时显示到屏幕上?有多少图片须要筹备好以便马上显示到屏幕?
- 设施的屏幕大小和密度是多少?高密度的设施须要更大的缓存空间来缓存同样数量的图片。
- Bitmap 的尺寸配置是多少,破费多少内存?
- 图片被拜访的频率如何?如果其中一些比另外一些拜访更频繁,那么咱们可能心愿在内存中保留那些最常拜访的图片,或者依据拜访频率给 Bitmap 分组,为不同的 Bitmap 组设置多个 LruCache 对象。
- 是否能够在缓存图片的品质和数量之间寻找平衡点?有时,保留大量低质量的 Bitmap 会十分有用,加载更高质量的图片的工作能够交给另外一个后盾线程解决。
- 缓存太小会导致额定的花销却没有显著的益处,缓存太大同样会导致 java.lang.OutOfMemory 的异样,并且使得你的程序只留下小局部的内存用来工作(缓存占用太多内存,导致其余操作会因为内存不够而抛出异样)。所以,咱们须要剖析理论状况之后,提出一个适合的解决方案。
-
LruCache是Android提供的一个缓存类,通常使用于内存缓存
- LruCache是一个泛型类,它的底层是用一个LinkedHashMap以强援用的形式存储外界的缓存对象来实现的。
-
为什么应用LinkedHashMap来作为LruCache的存储,是因为LinkedHashMap有两种排序形式,一种是插入排序形式,一种是拜访排序形式,默认状况下是以拜访形式来存储缓存对象的;LruCache提供了get和put办法来实现缓存的获取和增加,当缓存满时,会将最近起码应用的对象移除掉,而后再增加新的缓存对象。如下源码所示,底层是LinkedHashMap。
public LruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap(0, 0.75f, true);
}
-
在应用LruCache的时候,首先须要获取以后设施的内存容量,通常状况下会将总容量的八分之一作为LruCache的容量,而后重写LruCache的sizeof办法,sizeof办法用于计算缓存对象的大小,单位须要与调配的容量的单位统一;
// 获取零碎最大缓存
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// set LruCache size;
// 应用最大可用内存值的1/8作为缓存的大小
int cacheSize = maxMemory / 8;
LruCache memoryCache = new LruCache(cacheSize) {
@Override
protected int sizeOf(@NonNull String uri, @NonNull Bitmap bitmap) {
// 重写此办法来掂量每张图片的大小,默认返回图片数量
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
};
//插入对象
memoryCache.put(key, bitmap);
//取出对象
memoryCache.get(key);
-
如何淘汰缓存
- 这个就要看LinkedHashMap汇合的特点呢!LinkedHashMap 构造函数的第三个参数:accessOrder,传入true时, 元素会按拜访顺序排列,最初拜访的在遍历器最初端。在进行淘汰时,移除遍历器前端的元素,直至缓存总大小升高到指定大小以下。
5.2 Lru内存注意事项
-
看一个实在的场景
- 假如咱们的LruCache能够缓存80张,每次刷新从网络获取20张图片且不反复,那么在刷新第五次的时候,依据LruCache缓存的规定,第一次刷新的20张图片就会从LruCache中移出,处于期待被零碎GC的状态。如果咱们持续刷新n次,期待被回收的张数就会累积到 20 * n 张。
-
会呈现什么问题
- 会呈现大量的Bitmap内存碎片,咱们不晓得零碎什么时候会触发GC回收掉这些无用的Bitmap,对于内存是否会溢出,是否会频繁GC导致卡顿等未知问题。
-
解决方案该怎么做?
- 第一种:在3.0当前引入了 BitmapFactory.Options.inBitmap,如果设置此项,须要解码的图片就会尝试应用该Bitmap的内存,这样勾销了内存的动态分配,进步了性能,节俭了内存。
- 第二种:把处于无用的状态的Bitmap放入SoftReference。SoftReference援用的对象会在内存溢出之前被回收。
- 对于Lru缓存案例和代码能够参考:AppLruCache
5.3 应用Lru磁盘缓存
- 内存缓存可能进步拜访最近用过的 Bitmap 的速度,然而咱们无奈保障最近拜访过的 Bitmap 都可能保留在缓存中。像相似 GridView 等须要大量数据填充的控件很容易就会用尽整个内存缓存。另外,咱们的利用可能会被相似打电话等行为而暂停并退到后盾,因为后盾利用可能会被杀死,那么内存缓存就会被销毁,外面的 Bitmap 也就不存在了。一旦用户复原利用的状态,那么利用就须要重新处理那些图片。
- 磁盘缓存能够用来保留那些曾经解决过的 Bitmap,它还能够缩小那些不再内存缓存中的 Bitmap 的加载次数。当然从磁盘读取图片会比从内存要慢,而且因为磁盘读取操作工夫是不可预期的,读取操作须要在后盾线程中解决。
- 留神:如果图片会被更频繁的拜访,应用 ContentProvider 或者会更加适合,比方在图库利用中。
- 留神:因为初始化磁盘缓存波及到 I/O 操作,所以它不应该在主线程中进行。然而这也意味着在初始化实现之前缓存能够被拜访。为了解决这个问题,在下面的实现中,有一个锁对象(lock object)来确保在磁盘缓存实现初始化之前,利用无奈对它进行读取。
- 内存缓存的查看是能够在 UI 线程中进行的,磁盘缓存的查看须要在后盾线程中解决。磁盘操作永远都不应该在 UI 线程中产生。当图片解决实现后,Bitmap 须要增加到内存缓存与磁盘缓存中,不便之后的应用。
06.不同版本对Bitmap治理
6.1 演变过程
-
Android 2.3.3 (API level 10)以及之前,
- 一个 Bitmap 的像素数据是寄存在 Native 内存空间中的。这些数据与 Bitmap 对象自身是隔离的,Bitmap 自身被寄存在 Dalvik 堆中。并且无奈预测在 Native 内存中的像素级数据何时会被开释,这意味着程序容易超过它的内存限度并且解体。
-
Android 3.0 (API Level 11)开始
- 像素数据则是与 Bitmap 自身一起寄存在 Dalvik 堆中。
-
Android 8.0(Android O)及之后的版本中
- Bitmap 的像素数据的内存调配又回到了 Native 层,它是在 Native 堆空间进行调配的。
6.2 治理Bitmap内存
6.3 进步Bitmap复用
07.图片其余方面优化
7.1 缩小PNG图片的应用
- 这里要介绍一种新的图片格式:Webp,它是由 Google 推出的一种既保留 png 格局的长处,又可能缩小图片大小的一种新型图片格式。
- 在 Android 4.0(API level 14) 中反对有损的 WebP 图像,在 Android 4.3(API level 18) 和更高版本中反对无损和通明的 WebP 图像。
- 留神一下,Webp格局图片仅仅只是缩小图片的品质大小,并不会缩小加载图片后的内存占用。
7.2 切割圆角优化
7.3 如何给图片置灰色
7.4 如何解决图片旋转呢
7.5 保留图片且刷相册
7.6 对立图片域名优化
-
域名对立
- 缩小了10%+的反复图片下载和内存耗费。同时缩小之前多域名图片加载时反复创立HTTPS申请的过程,缩小图片加载工夫。
7.7 优化H5图片加载
7.8 优化图片暗影成果
-
暗影成果有哪些实现形式
- 第一种:应用CardView,然而不能设置暗影色彩
- 第二种:采纳shape叠加,存在前期UI成果不便优化
- 第三种:UI切图
- 第四种:自定义View
- 第五种:自定义Drawable
-
否定上背后两种计划起因剖析?
- 第一个计划的CardView渐变色和暗影成果很难管制,只能反对线性或者环装模式突变,这种不满足需要,因为暗影自身是一个周围一层很淡的色彩突围,在一个矩形框的层面上色彩大略统一,而且这个CardView有很多局限性,比方不能批改暗影的色彩,不能批改暗影的深浅。所以这个思路无奈实现这个需要。
- 第二个采纳shape叠加,能够实现暗影成果,然而影响UI,且暗影局部是占像素的,而且不灵便。
- 第三个计划询问了一下ui。他们给出的后果是如果应用切图的话那标注的话很难标,身为一个优良的设计师大多对像素点都和敏感,界面上的像素点有一点不协调那都是无奈容忍的。
-
网上一些介绍暗影成果计划
- 所有在深奥的技术,也都是为需要做筹备的。也就是须要实际并且能够用到理论开发中,这篇文章不再形象介绍暗影成果原理,了解三维空间中如何解决偏移光线达到暗影视差等,网上看了一些文章也没看明确或者了解。这篇博客间接通过调用api实现预期的成果。
- 多个drawable叠加,应用layer-list能够将多个drawable依照程序层叠在一起显示,默认状况下,所有的item中的drawable都会主动依据它附上view的大小而进行缩放,layer-list中的item是依照程序从下往上叠加的,即先定义的item在上面,前面的顺次往上面叠放
-
暗影是否占位
- 应用CardView暗影不占位,不能设置暗影色彩和成果
- 应用shape暗影是能够设置暗影色彩,然而是占位的
-
几种计划优缺点比照剖析
- CardView 长处:自带性能实现简略 毛病:自带圆角不肯定可适配所有需要
- layer(shape叠加) 长处:实现模式简略 毛病:成果个别
- 自定义实现 长处:实现成果好可配置能力高 毛病:须要开发者自行开发
-
对于解决暗影成果
- 具体各种计划的比照能够参考这个demo:AppShadowLib
7.9 图片资源的压缩
推荐阅读
-
本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ...
[详细]
蜡笔小新 2023-12-12 15:58:44
-
本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ...
[详细]
蜡笔小新 2023-12-14 18:23:25
-
-
本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ...
[详细]
蜡笔小新 2023-12-14 18:16:27
-
本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ...
[详细]
蜡笔小新 2023-12-14 17:46:55
-
本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ...
[详细]
蜡笔小新 2023-12-14 17:06:58
-
本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ...
[详细]
蜡笔小新 2023-12-13 19:47:31
-
篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ...
[详细]
蜡笔小新 2023-12-13 12:59:48
-
本文介绍了HTML中图像标签的使用和属性,包括定义图像、定义图像地图、使用源属性和替换文本属性。同时提供了相关实例和注意事项,帮助读者更好地理解和应用图像标签。 ...
[详细]
蜡笔小新 2023-12-13 11:31:26
-
本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ...
[详细]
蜡笔小新 2023-12-13 10:39:24
-
本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ...
[详细]
蜡笔小新 2023-12-12 21:40:02
-
本文介绍了如何突破MIUI14的限制,实现自定义胶囊图标和大图标样式,并支持任意APP。需要一定的动手能力和主题设计师账号权限或者会主题pojie。详细步骤包括应用包名获取、素材制作和封包获取等。 ...
[详细]
蜡笔小新 2023-12-12 12:07:16
-
PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ...
[详细]
蜡笔小新 2023-12-12 10:25:39
-
本文介绍了使用jQuery解决文件名过长导致下载失败的问题。原方案中存在文件名部分丢失的问题,通过动态生成隐藏域表单并提交的方式来解决。详细的解决方案和代码示例在文章中给出。 ...
[详细]
蜡笔小新 2023-12-11 16:59:20
-
本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ...
[详细]
蜡笔小新 2023-12-11 14:13:46
-
本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ...
[详细]
蜡笔小新 2023-12-11 12:26:25
-