Android开发笔记(一百七十四)图像解码器ImageDecoder

早期的Android只支持三种图像格式,分别是JPEG、PNG和GIF,虽然这三类图片都能在ImageView上显示,但对于GIF格式来说,图像视图仅能显示动图的初始画面,无法直接播放动画效果。此外,由于JPEG、PNG和GIF三兄弟历史悠久,当时的图像压缩算法不尽完美,并且手机摄像头的分辨率越来越高,导致一张高清照片动辄几M乃至十几M大小,使得手机的存储空间越发吃紧,这也要求更高效的压缩算法。
目前智能手机行业仅剩安卓和iOS两大阵营,为了争夺移动互联网时代的技术高地,两大阵营的盟主纷纷推出新的图像压缩算法,安卓阵营的谷歌推出了WebP格式,而iOS阵营的苹果推出了HEIF格式。尽管WebP与HEIF出自不同的厂商,但它俩都具备了下列的优异特性:
1、支持透明背景;(JPEG不支持透明背景)
2、支持动画效果;(JPEG和PNG不支持动画效果)
3、支持有损压缩;(PNG和GIF不支持有损压缩,因此它们的图片体积较大)
正因为WebP与HEIF如此优秀,所以它们在手机上愈加流行,从Android9开始便支持浏览这两种格式的图片,从Android10开始更允许将拍摄的照片保存为HEIF格式(同时需要硬件支持)。ImageDecoder正是Android9推出的新型图像解码器,它不但兼容常规的JPEG和PNG图片,还适配GIF、WebP、HEIF的动图效果,可谓新老图片类型一网打尽。利用图像解码器加载并显示图片的步骤分为以下三步:
1、调用ImageDecoder的createSource方法,从指定地方获得数据源;
2、调用ImageDecoder的decodeDrawable方法,从数据源解码得到Drawable类型的图形信息;
3、调用图像视图的setImageDrawable,设置图像视图的图形对象;
其中第一步的createSource方法允许从多处来源读取图像信息,包括但不限于:
1、来自存储卡的File对象;
2、来自系统相册的Uri对象;
3、来自资源图片的图形编号;
4、从输入流获取的字节数组;
举个例子,现在准备通过ImageDecoder加载相册中的某张图片,此时从系统媒体库得到Uri类型的图片路径,则详细的图像加载代码示例如下:

// 利用Android9.0新增的ImageDecoder读取图片
ImageDecoder.Source source = ImageDecoder.createSource(getContentResolver(), imageUri);
// 从数据源解码得到图形信息
Drawable drawable = ImageDecoder.decodeDrawable(source);
iv_photo.setImageDrawable(drawable); // 设置图像视图的图形对象

单看上述的加载代码,似乎ImageDecoder并无什么优势,因为若是JPEG或者PNG图片,直接调用图像视图的setImageURI方法即可。当然,ImageDecoder的存在意义是为了处理新的图片格式,而不是在老格式上一争高下。它主要在如下两个方面做了增强:
(1)调用带两个参数的decodeDrawable方法,此时输入第二个监听器参数,在监听器中可以获得图像的媒体类型,以及该图像是否为动图;
(2)判断解码得到的图形对象是否为Animatable类型,如果是的话,则调用start方法播放动画;
根据上述两个增强手段,补齐后的动图播放代码如下所示:

// 显示指定来源的图像
private void showImageSource(ImageDecoder.Source source) throws IOException {
    // 从数据源解码得到图形信息
    Drawable drawable = ImageDecoder.decodeDrawable(source, new OnHeaderDecodedListener() {
        @Override
        public void onHeaderDecoded(ImageDecoder decoder, ImageDecoder.ImageInfo info, ImageDecoder.Source source) {
            // 获取图像信息的媒体类型与是否动图
            String desc = String.format("该图片类型为%s,它%s动图",
                    info.getMimeType(), info.isAnimated()?"是":"不是");
            tv_info.setText(desc);
        }
    });
    iv_pic.setImageDrawable(drawable); // 设置图像视图的图形对象
    if (drawable instanceof Animatable) { // 如果是动画图形,则开始播放动画
        ((Animatable) iv_pic.getDrawable()).start();
    }
}

接着给出一张GIF图片,运行包含以上代码的测试App,观察到动图播放效果如下面两图所示。
在这里插入图片描述
在这里插入图片描述

再分别给出WebP图片与HEIF图片,重新运行测试App,观察到图像浏览界面如下面两图所示。
在这里插入图片描述
在这里插入图片描述

至此充分展示了图像解码器的强大功能,它不仅支持WebP与HEIF这两种新兴图片格式,还能直接播放动图的动画特效。

点此查看Android开发笔记的完整目录

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Transformer解码器是一种用于自然语言处理任务的神经网络模型,它是Transformer模型的重要组成部分。Transformer解码器主要用于生成目标序列,如机器翻译、文本生成等任务。 Transformer解码器的结构由多个相同的层组成,每个层都包含了自注意力机制和前馈神经网络。在自注意力机制中,解码器可以关注输入序列中的不同位置,并根据这些位置的重要性来调整生成目标序列的权重。前馈神经网络则负责对输入进行非线性变换。 在解码过程中,Transformer解码器通过逐步生成目标序列的方式进行。首先,它会接收一个特殊的起始符号作为输入,并生成第一个目标词。然后,它将生成的目标词与编码器输出进行注意力计算,得到上下文向量。接下来,上下文向量会与之前生成的目标词一起输入到下一个解码层中,生成下一个目标词。这个过程会一直进行,直到生成完整的目标序列。 Transformer解码器相比于传统的循环神经网络(RNN)解码器具有以下优势: 1. 并行计算:Transformer解码器可以同时处理整个序列,而不需要按顺序逐个生成目标词,从而加快了计算速度。 2. 长距离依赖:由于自注意力机制的存在,Transformer解码器可以更好地捕捉输入序列中的长距离依赖关系。 3. 模块化结构:Transformer解码器的每个层都是相互独立的,可以方便地进行扩展和修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值