多媒体——图片——图像解码器ImageDecoder
图像解码器ImageDecoder
早期的Android只支持三种图像格式:JPEG、PNG和GIF,而且图像视图仅能显示动图的初始画面,无法直接播放动画效果。
时代呼唤技术更先进的图像压缩算法,谷歌推出了WebP格式,苹果推出了HEIF格式。WebP与HEIF都具备了下列特性:
(1)支持透明背景;(JPEG不支持透明背景)
(2)支持动画效果;(JPEG和PNG不支持动画效果)
(3)支持有损压缩;(PNG和GIF不支持有损压缩,因此它们的图片体积较大)
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal" android:layout_marginLeft="5dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="图像类型:" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_type" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:spinnerMode="dialog" /> </LinearLayout> <TextView android:id="@+id/tv_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:textColor="#000000" android:textSize="17sp"/> <ImageView android:id="@+id/iv_pic" android:layout_width="match_parent" android:layout_height="250dp" android:scaleType="fitCenter" /> </LinearLayout>
item_select.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:singleLine="true" android:gravity="center" android:textSize="17sp" android:textColor="#0000ff" />
代码:
package com.example.myapplication; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; 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; @RequiresApi(api = Build.VERSION_CODES.P) public class MainActivity extends AppCompatActivity { private TextView tv_info; // 声明一个文本视图对象 private ImageView iv_pic; // 声明一个图像视图对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_info = findViewById(R.id.tv_info); iv_pic = findViewById(R.id.iv_pic); initTypeSpinner(); // 初始化图像类型下拉框 } private String[] typeArray = {"直接显示GIF", "直接显示WebP", "显示GIF动图", "显示WebP动图", "显示HEIF图片"}; // 初始化图像类型下拉框 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 MainActivity.ImageTypeListener()); sp_type.setSelection(0); } 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); // 从输入流中读取字节数组 ImageDecoder.Source source = ImageDecoder.createSource(ByteBuffer.wrap(bytes)); // 利用Android 9.0新增的ImageDecoder读取图片 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() { @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(); } } }