[其他] 多媒体——图片——图像解码器ImageDecoder

[复制链接]
 楼主| lvuu 发表于 2023-2-25 11:16 | 显示全部楼层 |阅读模式
图像解码器ImageDecoder

早期的Android只支持三种图像格式:JPEG、PNG和GIF,而且图像视图仅能显示动图的初始画面,无法直接播放动画效果。

时代呼唤技术更先进的图像压缩算法,谷歌推出了WebP格式,苹果推出了HEIF格式。WebP与HEIF都具备了下列特性:

(1)支持透明背景;(JPEG不支持透明背景)(2)支持动画效果;(JPEG和PNG不支持动画效果)(3)支持有损压缩;(PNG和GIF不支持有损压缩,因此它们的图片体积较大)
9319063f97d816e3d4.png

3657363f97d90de134.png

评论

版权声明:本文为CSDN博主「小白龙白龙马」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_61442607/article/details/127160323  发表于 2023-2-25 11:17
 楼主| lvuu 发表于 2023-2-25 11:17 | 显示全部楼层
布局:
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:layout_width="match_parent"
  3.     android:layout_height="match_parent"
  4.     android:orientation="vertical">

  5.     <LinearLayout
  6.         android:layout_width="match_parent"
  7.         android:layout_height="40dp"
  8.         android:orientation="horizontal"
  9.         android:layout_marginLeft="5dp" >

  10.         <TextView
  11.             android:layout_width="wrap_content"
  12.             android:layout_height="wrap_content"
  13.             android:text="图像类型:"
  14.             android:textColor="@color/black"
  15.             android:textSize="17sp" />

  16.         <Spinner
  17.             android:id="@+id/sp_type"
  18.             android:layout_width="0dp"
  19.             android:layout_height="wrap_content"
  20.             android:layout_weight="1"
  21.             android:spinnerMode="dialog" />

  22.     </LinearLayout>

  23.     <TextView
  24.         android:id="@+id/tv_info"
  25.         android:layout_width="match_parent"
  26.         android:layout_height="wrap_content"
  27.         android:layout_marginLeft="5dp"
  28.         android:textColor="#000000"
  29.         android:textSize="17sp"/>

  30.     <ImageView
  31.         android:id="@+id/iv_pic"
  32.         android:layout_width="match_parent"
  33.         android:layout_height="250dp"
  34.         android:scaleType="fitCenter" />

  35. </LinearLayout>

 楼主| lvuu 发表于 2023-2-25 11:20 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:22 | 显示全部楼层
item_select.xml
  1. <TextView xmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:layout_width="match_parent"
  3.     android:layout_height="50dp"
  4.     android:singleLine="true"
  5.     android:gravity="center"
  6.     android:textSize="17sp"
  7.     android:textColor="#0000ff" />

 楼主| lvuu 发表于 2023-2-25 11:22 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:23 | 显示全部楼层
代码:

  1. package com.example.myapplication;

  2. import androidx.annotation.RequiresApi;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import android.graphics.ImageDecoder;
  5. import android.graphics.ImageDecoder.OnHeaderDecodedListener;
  6. import android.graphics.drawable.Animatable;
  7. import android.graphics.drawable.Drawable;
  8. import android.os.Build;
  9. import android.os.Bundle;
  10. import android.view.View;
  11. import android.widget.AdapterView;
  12. import android.widget.ArrayAdapter;
  13. import android.widget.ImageView;
  14. import android.widget.Spinner;
  15. import android.widget.TextView;
  16. import java.io.IOException;
  17. import java.io.InputStream;
  18. import java.nio.ByteBuffer;

  19. @RequiresApi(api = Build.VERSION_CODES.P)
  20. public class MainActivity extends AppCompatActivity
  21. {

  22.     private TextView tv_info; // 声明一个文本视图对象
  23.     private ImageView iv_pic; // 声明一个图像视图对象

  24.     @Override
  25.     protected void onCreate(Bundle savedInstanceState)
  26.     {
  27.         super.onCreate(savedInstanceState);
  28.         setContentView(R.layout.activity_main);


  29.         tv_info = findViewById(R.id.tv_info);
  30.         iv_pic = findViewById(R.id.iv_pic);

  31.         initTypeSpinner(); // 初始化图像类型下拉框
  32.     }

  33.     private String[] typeArray = {"直接显示GIF", "直接显示WebP", "显示GIF动图", "显示WebP动图", "显示HEIF图片"};


  34.     // 初始化图像类型下拉框
  35.     private void initTypeSpinner()
  36.     {

  37.         ArrayAdapter<String> typeAdapter = new ArrayAdapter<String>(this, R.layout.item_select, typeArray);

  38.         Spinner sp_type = findViewById(R.id.sp_type);

  39.         sp_type.setPrompt("请选择图像类型");

  40.         sp_type.setAdapter(typeAdapter);

  41.         sp_type.setOnItemSelectedListener(new MainActivity.ImageTypeListener());

  42.         sp_type.setSelection(0);
  43.     }

  44.     class ImageTypeListener implements AdapterView.OnItemSelectedListener
  45.     {

  46.         public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
  47.         {

  48.             if (arg2 == 0)
  49.             {
  50.                 tv_info.setText("");
  51.                 iv_pic.setImageResource(R.drawable.happy);
  52.             }
  53.             else if (arg2 == 1)
  54.             {
  55.                 tv_info.setText("");
  56.                 iv_pic.setImageResource(R.drawable.world_cup_2014);
  57.             }
  58.             else if (arg2 == 2)
  59.             {
  60.                 showImage(R.drawable.happy); // 显示gif和webp图片
  61.             }
  62.             else if (arg2 == 3)
  63.             {
  64.                 showImage(R.drawable.world_cup_2014); // 显示gif和webp图片
  65.             }
  66.             else if (arg2 == 4)
  67.             {
  68.                 showHeic(R.raw.lotus); // 显示Heif图片(扩展名为heif或者heic)
  69.             }
  70.         }

  71.         public void onNothingSelected(AdapterView<?> arg0) {}
  72.     }




  73.     // 显示Heif图片(扩展名为heif或者heic)
  74.     private void showHeic(int imageId)
  75.     {

  76.         try (InputStream is = getResources().openRawResource(imageId)) // 从资源文件中获取输入流对象
  77.         {
  78.             byte[] bytes = new byte[is.available()]; // 创建临时存放的字节数组

  79.             is.read(bytes); // 从输入流中读取字节数组


  80.             ImageDecoder.Source source = ImageDecoder.createSource(ByteBuffer.wrap(bytes)); // 利用Android 9.0新增的ImageDecoder读取图片

  81.             showImageSource(source); // 显示指定来源的图像
  82.         }
  83.         catch (Exception e)
  84.         {
  85.             e.printStackTrace();
  86.         }
  87.     }




  88.     // 显示gif和webp图片

  89.     private void showImage(int imageId)
  90.     {
  91.         try
  92.         {
  93.             // 利用Android 9.0新增的ImageDecoder读取图片
  94.             ImageDecoder.Source source = ImageDecoder.createSource(getResources(), imageId);

  95.             showImageSource(source); // 显示指定来源的图像
  96.         }
  97.         catch (Exception e)
  98.         {
  99.             e.printStackTrace();
  100.         }
  101.     }




  102.     // 显示指定来源的图像
  103.     private void showImageSource(ImageDecoder.Source source) throws IOException
  104.     {
  105.         // 从数据源解码得到图形信息
  106.         Drawable drawable = ImageDecoder.decodeDrawable(source, new OnHeaderDecodedListener() {
  107.             @Override
  108.             public void onHeaderDecoded(ImageDecoder decoder, ImageDecoder.ImageInfo info, ImageDecoder.Source source) {
  109.                 // 获取图像信息的媒体类型与是否动图
  110.                 String desc = String.format("该图片类型为%s,它%s动图",
  111.                         info.getMimeType(), info.isAnimated()?"是":"不是");
  112.                 tv_info.setText(desc);
  113.             }
  114.         });

  115.         iv_pic.setImageDrawable(drawable); // 设置图像视图的图形对象

  116.         if (drawable instanceof Animatable)  // 如果是动画图形,则开始播放动画
  117.         {
  118.             ((Animatable) iv_pic.getDrawable()).start();
  119.         }
  120.     }

  121. }

 楼主| lvuu 发表于 2023-2-25 11:23 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:23 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:23 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:24 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:24 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:24 | 显示全部楼层
 楼主| lvuu 发表于 2023-2-25 11:24 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

70

主题

612

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

70

主题

612

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部