Android UI 之 ImageView

Posted Kevin_小飞象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android UI 之 ImageView相关的知识,希望对你有一定的参考价值。

ImageView 继承自 View 的组件,主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何 Drawable 对象都可以使用 ImageView 来显示。

一. 基本使用

  1. 效果图
    在这里插入图片描述

  2. 布局文件

<ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
  1. 动态设置图片
<ImageView
        android:id="@+id/iv_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"/>
public class TestActivity extends BaseActivity {
    @BindView(R.id.iv_image)
    ImageView mImageView;

    @Override
    public int getLayoutId() {
        return R.layout.activity_test;
    }

    @Override
    public void initView() {
        mImageView.setImageBitmap(BitmapUtil.getBitmapFromDrawable(getResources().getDrawable(R.mipmap.ic_avatar)));
    }
}

二、图片倒影实现

  1. 效果图
    在这里插入图片描述
  2. 布局文件
<ImageView
        android:id="@+id/iv_image2"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@color/grey"
        android:padding="5dp" />

3.代码逻辑

public class TestActivity extends BaseActivity {
    @BindView(R.id.iv_image2)
    ImageView mImageView2;

    @Override
    public int getLayoutId() {
        return R.layout.activity_test;
    }

    @Override
    public void initView() {
        Bitmap bitmap = BitmapUtil.getBitmapFromDrawable(getResources().getDrawable(R.mipmap.meizi));
        mImageView2.setImageBitmap(BitmapUtil.createReflectionBitmap(bitmap));
    }
}

三、图片圆角实现

  1. 效果图
    在这里插入图片描述
  2. 布局文件
<ImageView
        android:id="@+id/iv_image3"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:background="@color/grey"
        android:layout_marginTop="12dp"
        android:padding="5dp" />
  1. 逻辑代码
public class TestActivity extends BaseActivity {
    @BindView(R.id.iv_image3)
    ImageView mImageView3;

    @Override
    public int getLayoutId() {
        return R.layout.activity_test;
    }

    @Override
    public void initView() {
        Bitmap bitmap = BitmapUtil.getBitmapFromDrawable(getResources().getDrawable(R.mipmap.meizi));
        mImageView3.setImageBitmap(BitmapUtil.getRoundedCornerBitmap(bitmap,60.0f));
    }
}

四、实现怀旧照片

  1. 效果图
    在这里插入图片描述
  2. 布局文件
<ImageView
        android:id="@+id/iv_image2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp" />
  1. 逻辑代码
public class TestActivity extends BaseActivity {
    @BindView(R.id.iv_image2)
    ImageView mImageView2;


    @Override
    public int getLayoutId() {
        return R.layout.activity_test;
    }

    @Override
    public void initView() {
        Bitmap bitmap = BitmapUtil.getBitmapFromDrawable(getResources().getDrawable(R.mipmap.meizi));
        mImageView2.setImageBitmap(BitmapUtil.convertToBlackWhite(bitmap));
    }
}

BitmapUtil 工具类

package com.hk.launcherdemo.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.util.Log;
import android.view.View;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created on 2021/7/14 16:46
 *
 * @author Gong Youqiang
 */
public class BitmapUtil {
    private static final boolean DEBUG = false;
    private static final String TAG = BitmapUtil.class.getSimpleName();

    /**
     * Don't let anyone instantiate this class.
     */
    private BitmapUtil() {
        throw new Error("Do not need instantiate!");
    }

    /**
     * 图片压缩处理(使用Options的方法)
     * <p/>
     * <br>
     * <b>说明</b> 使用方法:
     * 首先你要将Options的inJustDecodeBounds属性设置为true,BitmapFactory.decode一次图片 。
     * 然后将Options连同期望的宽度和高度一起传递到到本方法中。
     * 之后再使用本方法的返回值做参数调用BitmapFactory.decode创建图片。
     * <p/>
     * <br>
     * <b>说明</b> BitmapFactory创建bitmap会尝试为已经构建的bitmap分配内存
     * ,这时就会很容易导致OOM出现。为此每一种创建方法都提供了一个可选的Options参数
     * ,将这个参数的inJustDecodeBounds属性设置为true就可以让解析方法禁止为bitmap分配内存
     * ,返回值也不再是一个Bitmap对象, 而是null。虽然Bitmap是null了,但是Options的outWidth、
     * outHeight和outMimeType属性都会被赋值。
     *
     * @param reqWidth  目标宽度,这里的宽高只是阀值,实际显示的图片将小于等于这个值
     * @param reqHeight 目标高度,这里的宽高只是阀值,实际显示的图片将小于等于这个值
     */
    public static BitmapFactory.Options calculateInSampleSize(
            final BitmapFactory.Options options, final int reqWidth,
            final int reqHeight) {
        // 源图片的高度和宽度
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > 400 || width > 450) {
            if (height > reqHeight || width > reqWidth) {
                // 计算出实际宽高和目标宽高的比率
                final int heightRatio = Math.round((float) height
                        / (float) reqHeight);
                final int widthRatio = Math.round((float) width
                        / (float) reqWidth);
                // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
                // 一定都会大于等于目标的宽和高。
                inSampleSize = heightRatio < widthRatio ? heightRatio
                        : widthRatio;
            }
        }
        // 设置压缩比例
        options.inSampleSize = inSampleSize;
        options.inJustDecodeBounds = false;
        return options;
    }

    /**
     * 获取一个指定大小的bitmap
     *
     * @param res       Resources
     * @param resId     图片ID
     * @param reqWidth  目标宽度
     * @param reqHeight 目标高度
     */
    public static Bitmap getBitmapFromResource(Resources res, int resId,
                                               int reqWidth, int reqHeight) {
        // BitmapFactory.Options options = new BitmapFactory.Options();
        // options.inJustDecodeBounds = true;
        // BitmapFactory.decodeResource(res, resId, options);
        // options = BitmapHelper.calculateInSampleSize(options, reqWidth,
        // reqHeight);
        // return BitmapFactory.decodeResource(res, resId, options);

        // 通过JNI的形式读取本地图片达到节省内存的目的
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Config.RGB_565;
        options.inPurgeable = true;
        options.inInputShareable = true;
        InputStream is = res.openRawResource(resId);
        return getBitmapFromStream(is, null, reqWidth, reqHeight);
    }

    /**
     * 获取一个指定大小的bitmap
     *
     * @param reqWidth  目标宽度
     * @param reqHeight 目标高度
     */
    public static Bitmap getBitmapFromFile(String pathName, int reqWidth,
                                           int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        options = calculateInSampleSize(options, reqWidth, reqHeight);
        return BitmapFactory.decodeFile(pathName, options);
    }

    /**
     * 获取一个指定大小的bitmap
     *
     * @param data      Bitmap的byte数组
     * @param offset    image从byte数组创建的起始位置
     * @param length    the number of bytes, 从offset处开始的长度
     * @param reqWidth  目标宽度
     * @param reqHeight 目标高度
     */
    public static Bitmap getBitmapFromByteArray(byte[] data, int offset,
                                                int length, int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, offset, length, options);
        options = calculateInSampleSize(options, reqWidth, reqHeight);
        return BitmapFactory.decodeByteArray(data, offset, length, options);
    }

    /**
     * 把bitmap转化为bytes
     *
     * @param bitmap 源Bitmap
     * @return Byte数组
     */
    public static byte[] getBytesFromBitmap(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    /**
     * Stream转换成Byte
     *
     * @param inputStream InputStream
     * @return Byte数组
     */
    public static byte[] getBytesFromStream(InputStream inputStream) {
        ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
        byte[] buffer = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buffer)) >= 0) {
                os.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return os.toByteArray();
    }

    /**
     * 获取一个指定大小的bitmap
     *
     * @param b Byte数组
     * @return 需要的Bitmap
     */
    public static Bitmap getBitmapFromBytes(byte[] b) {
        if (b.length != 0) {
            return BitmapFactory.decodeByteArray(b, 0, b.length);
        } else {
            return null;
        }
    }


    /**
     * 获取一个指定大小的bitmap
     *
     * @param is         从输入流中读取Bitmap
     * @param outPadding If not null, return the padding rect for the bitmap if it
     *                   exists, otherwise set padding to [-1,-1,-1,-1]. If no bitmap
     *                   is returned (null) then padding is unchanged.
     * @param reqWidth   目标宽度
     * @param reqHeight  目标高度
     */
    public static Bitmap getBitmapFromStream(InputStream is, Rect outPadding,
                                             int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, outPadding, options);
        options = calculateInSampleSize(options, reqWidth, reqHeight);
        return BitmapFactory.decodeStream(is, outPadding, options);
    }

    /**
     * 从View获取Bitmap
     *
     * @param view View
     * @return Bitmap
     */
    public static Bitmap getBitmapFromView(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
                Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        view.layout(view.getLeft(), view.getTop(), view.getRight(),
                view.getBottom());
        view.draw(canvas);

        return bitmap;
    }

    /**
     * 把一个View的对象转换成bitmap
     *
     * @param view View
     * @return Bitmap
     */
    public static Bitmap getBitmapFromView2(View view) {

        view.clearFocus();
        view.setPressed(false);

        // 能画缓存就返回false
        boolean willNotCache = view.willNotCacheDrawing();
        view.setWillNotCacheDrawing(false);
        int color = view.getDrawingCacheBackgroundColor();
        view.setDrawingCacheBackgroundColor(0);
        if (color != 0) {
            view.destroyDrawingCache();
        }
        view.buildDrawingCache();
        Bitmap cacheBitmap = view.getDrawingCache();
        if (cacheBitmap == null) {
            if (DEBUG) {
                Log.e(TAG, "failed getViewBitmap(" + view 以上是关于Android UI 之 ImageView的主要内容,如果未能解决你的问题,请参考以下文章

UI控件之显示图像控件ImageView(下)

Android UI 之 ImageView

UI控件之显示图像控件ImageView(上)

Android开发系列之UI开发

Android培训准备资料之UI一些相似控件和控件一些相似属性之间的区别

android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明