需要源码和图片集请点赞关注收藏后评论区留言~~~

一、图像解码器ImageDecoder

早期的Android只支持3种图像格式,分别是JPEG,PNG,GIF 虽然这三类图片都能在ImageView上显示,但对于GIF格式图来说,图像视图仅仅能显示动图的初始画面,无法直接播放动画效果,并且随着图片大小 越来越大,使得手机存储空间越发吃紧,这也要求更高效的压缩算法

目前智能手机行业仅剩安卓和IOS两大阵营,两大阵营纷纷推出新的图像压缩算法,安卓推出了WebP格式,IOS推出了HEIF格式,它们都具备以下的优异特性

1:支持透明背景 JPEG不支持

2:支持动画效果 JPEG和PNG不支持动画效果

3:支持有损压缩 PNG和GIF不支持有损压缩 因为它们图片体积偏大

利用图像解码器加载并显示图片的步骤分为以下三步

1:调用ImageDecoder的createSource方法 从指定地方获得数据源

2:调用ImageDecoder的decodeDrawable方法 从数据源解码得到Drawable类型的图形信息

3:调用图像视图的setImageDrawable方法 设置图像视图的图形对象

ImageDecoder相比于传统方式主要有以下两个优点

1:调用带两个参数的decodeDrawable方法,此时输入第二个监听器参数,在监听器种可以获得图像的媒体类型,以及该图像是否为动图

2:判断解码得到的图形对象是否为Animatable类型,如果是的话,就调用start方法播放动画

效果如下 动图的播放动画已上传至我的个人主页 可前往观看~~~ 

代码如下

Java类

package com.example.chapter13;import androidx.appcompat.app.AppCompatActivity;import android.annotation.TargetApi;
import android.graphics.ImageDecoder;
import android.graphics.ImageDecoder.OnHeaderDecodedListener;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;@TargetApi(Build.VERSION_CODES.P)
public class ImageSpecialActivity extends AppCompatActivity {private TextView tv_info; // 声明一个文本视图对象private ImageView iv_pic; // 声明一个图像视图对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_image_special);tv_info = findViewById(R.id.tv_info);iv_pic = findViewById(R.id.iv_pic);initTypeSpinner(); // 初始化图像类型下拉框}// 初始化图像类型下拉框private void initTypeSpinner() {ArrayAdapter<String> typeAdapter = new ArrayAdapter<String>(this,R.layout.item_select, typeArray);Spinner sp_type = findViewById(R.id.sp_type);sp_type.setPrompt("请选择图像类型");sp_type.setAdapter(typeAdapter);sp_type.setOnItemSelectedListener(new ImageSpecialActivity.ImageTypeListener());sp_type.setSelection(0);}private String[] typeArray = {"直接显示GIF", "直接显示WebP", "显示GIF动图", "显示WebP动图", "显示HEIF图片"};class ImageTypeListener implements AdapterView.OnItemSelectedListener {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {if (arg2 == 0) {tv_info.setText("");iv_pic.setImageResource(R.drawable.happy);} else if (arg2 == 1) {tv_info.setText("");iv_pic.setImageResource(R.drawable.world_cup_2014);} else if (arg2 == 2) {showImage(R.drawable.happy); // 显示gif和webp图片} else if (arg2 == 3) {showImage(R.drawable.world_cup_2014); // 显示gif和webp图片} else if (arg2 == 4) {showHeic(R.raw.lotus); // 显示Heif图片(扩展名为heif或者heic)}}public void onNothingSelected(AdapterView<?> arg0) {}}// 显示Heif图片(扩展名为heif或者heic)private void showHeic(int imageId) {try (InputStream is = getResources().openRawResource(imageId)) { // 从资源文件中获取输入流对象byte[] bytes = new byte[is.available()]; // 创建临时存放的字节数组is.read(bytes); // 从输入流中读取字节数组// 利用Android 9.0新增的ImageDecoder读取图片ImageDecoder.Source source = ImageDecoder.createSource(ByteBuffer.wrap(bytes));showImageSource(source); // 显示指定来源的图像} catch (Exception e) {e.printStackTrace();}}// 显示gif和webp图片private void showImage(int imageId) {try {// 利用Android 9.0新增的ImageDecoder读取图片ImageDecoder.Source source = ImageDecoder.createSource(getResources(), imageId);showImageSource(source); // 显示指定来源的图像} catch (Exception e) {e.printStackTrace();}}// 显示指定来源的图像private void showImageSource(ImageDecoder.Source source) throws IOException {// 从数据源解码得到图形信息Drawable drawable = ImageDecoder.decodeDrawable(source, new OnHeaderDecodedListener() {@Overridepublic 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();}}}

解码器类

package com.example.chapter13;import androidx.appcompat.app.AppCompatActivity;import android.annotation.TargetApi;
import android.content.Intent;
import android.graphics.ImageDecoder;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;@TargetApi(Build.VERSION_CODES.P)
public class ImageDecoderActivity extends AppCompatActivity implements View.OnClickListener {private final static String TAG = "ImageDecoderActivity";private ImageView iv_photo; // 声明一个图像视图对象private int CHOOSE_CODE = 3; // 选择照片的请求码@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_image_decoder);iv_photo = findViewById(R.id.iv_photo);findViewById(R.id.btn_choose).setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_choose) {// 创建一个内容获取动作的意图(准备跳到系统相册)Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT);albumIntent.setType("image/*"); // 设置内容类型为图像startActivityForResult(albumIntent, CHOOSE_CODE); // 打开系统相册}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent) {super.onActivityResult(requestCode, resultCode, intent);if (resultCode == RESULT_OK && requestCode == CHOOSE_CODE) {if (intent.getData() != null) { // 从相册选择一张照片Uri imageUri = intent.getData();showDecodedImage(imageUri); // 显示解码后的图像}}}// 显示解码后的图像private void showDecodedImage(Uri imageUri) {try {// 利用Android 9.0新增的ImageDecoder读取图片ImageDecoder.Source source = ImageDecoder.createSource(getContentResolver(), imageUri);// 从数据源解码得到图形信息Drawable drawable = ImageDecoder.decodeDrawable(source);iv_photo.setImageDrawable(drawable); // 设置图像视图的图形对象} catch (Exception e) {e.printStackTrace();}}}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:orientation="horizontal"android:layout_marginLeft="5dp" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="图像类型:"android:textColor="@color/black"android:textSize="17sp" /><Spinnerandroid:id="@+id/sp_type"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:spinnerMode="dialog" /></LinearLayout><TextViewandroid:id="@+id/tv_info"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:textColor="#000000"android:textSize="17sp"/><ImageViewandroid:id="@+id/iv_pic"android:layout_width="match_parent"android:layout_height="250dp"android:scaleType="fitCenter" /></LinearLayout>

创作不易 觉得有帮助请 点赞关注收藏~~~

Android Studio App开发之利用图像解码器ImageDecoder播放GIF动图、Webp、HEIF图片(附源码 简单实用)相关推荐

  1. Android App开发手机阅读中PDF文件渲染器的讲解及使用(附源码 简单易懂)

    需要源码和图片集请点赞关注收藏后评论区留言~~~ 一.PDF文件渲染器 Android集成了PDF的渲染操作,从很大程度上方便了开发者,这个PDF文件渲染器便是PdfRenderer.渲染器允许从存储 ...

  2. C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码

    今天的学习内容? 今天我们讲讲Xamarin中的MVVM双向绑定,嗯..需要有一定的MVVM基础.,具体什么是MVVM - -,请百度,我就不多讲了 效果如下: 正文 1.简单的入门Demo 这个时间 ...

  3. C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码

    前言 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一篇博文被博客园的编辑大哥置顶了.感谢. 评论也很多,褒贬 ...

  4. Python对带光晕的任意纯色背景图像进行去背景色操作(保留透明效果、附源码)

    昨天更新了一个去黑色背景的文章,今天发现可以再适用范围上推广一下,前提是知道背景色的RGB值. Python对带光晕的图像进行去黑底黑色背景操作(附源码) 先上效果图 除了纯白会导致透明度异常,纯红导 ...

  5. Android Studio App开发之下载管理器DownloadManager中显示、轮询下载进度、利用POST上传文件讲解及实战(附源码)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.在通知栏显示下载进度 利用GET方式读取数据有很多缺点比如1:无法端点续传 一旦中途失败只能重新获取 2:不是真正意义上的下载操作 无法设置参 ...

  6. Android Studio App开发之网络通信中使用POST方式调用HTTP接口实现应用更新功能(附源码 超详细必看)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.POST方式调用HTTP接口 POST方式把接口地址与请求报文分开,允许使用自定义的报文格式,由此扩大了该方式的应用场景.POST请求与GET ...

  7. Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.使用录音机录制音频 手机有自带的系统相机,也有自带的系统录音机,只要在调用startActivityForResult之前指定该动作,就会自动 ...

  8. Android Studio App开发之使用摄像机录制视频和从视频库中选取视频的讲解及实战(附源码)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.使用摄像机录制视频 与音频类似,通过系统摄像机可以很方便的录制视频,只要指定摄像动作为MediaStore.ACTION_VIDEO_CAPT ...

  9. Android Studio App开发之循环试图RecyclerView,布局管理器LayoutManager、动态更新循环视图讲解及实战(附源码)

    运行有问题或需要全部源码请点赞关注收藏后评论区留言~~~ 一.循环视图RecyclerView 尽管ListView和GridView分别实现了多行单列和多行多列的列表,使用也很简单,可是它们缺少变化 ...

最新文章

  1. 求大数的阶乘方法(数组)
  2. Qt信号与槽机制详解
  3. DAC0832的多功能信号/波形发生器Proteus仿真设计,4种波形(正弦、三角、方波、锯齿),附仿真+C程序+论文等
  4. H3C交换机 access端口配置
  5. 计算机安装系统后鼠标无法使用,电脑重装系统后鼠标键盘不能用怎么办
  6. Redis Hget 命令
  7. 鹏业安装算量智能计算综合布线功能操作
  8. Apache SeaTunnel(Incubating) 2.2.0-beta 版本发布!API 重构,连接器与引擎解偶
  9. 分享6种时间管理方法,不要再说时间不够用了!
  10. WIN10创建虚拟桌面
  11. 配置电脑计算机从哪几个,电脑硬件配置_电脑硬件配置有哪些
  12. git远程代码回滚_git 远程分支回滚
  13. 村医计算机在线考试答案,资讯详情-村医去卫生院换电脑,却被“威胁”停业整顿?-医德帮诊所生态服务平台-为基层诊所赋能...
  14. 浏览器如何截图整个滚动屏 ?
  15. 安卓移动开发实验:Android Studio设计微信界面
  16. 初学者:java练习题———含答案-------类与对象(2)
  17. Mol Cell Proteomics. |陈洁| 整合鸟枪法蛋白质组学中鉴定和定量的错误率
  18. 安全狗获聘福建省网络与信息安全信息通报中心技术支撑单位
  19. str.substring(0,str.length() -1)用法
  20. 华为交换机用命令更改已有admin账户开启SSH

热门文章

  1. 主机 来电 自动 开机 适合 软路由,也适合服务器
  2. 360加固保mac不能打开以及不能输入密码的解决方法
  3. Windows XP远程桌面连接
  4. iOS 14 Termius [No route to host] 解决方案
  5. Kotlin 2. Kotlin Suspend 挂起函数
  6. 【健康】血常规指标入门
  7. golang google authenticator
  8. 四川大学计算机学院保研复试,四川大学计算机学院计算机技术(专业学位)保研...
  9. 图片处理工具怎么处理图片?图片编辑工具怎么用?
  10. 【pygame】Python 制作 XP 经典扫雷游戏