我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android自定义视图中图片的处理

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android自定义视图中图片的处理

所谓游戏,本质就是提供更逼真的、能模拟某种环境的用户界面,并根据某种规则来响应用户操作。为了提供更逼真的用户界面,需要借助于图形、图像处理。

从广义的角度来看,Android应用中的图片不仅包括*.png、*.jpg、 *.gif等各种格式的位图,也包括使用XML资源文件定义的各种Drawable对象。

1.使用Drawable对象

为Android应用增加了Drawable资源之后,Android SDK会为这份资源在R清单文件中创建一个索引项:R.drawable.file_name。

获取方式:

  • 在XML资源文件中通过@drawablelfile_name访问该Drawable对象
  • 在Java代码中通过R.drawable.file_name访问该Drawable对象。

需要指出的是,R.drawable.file_name是一个int类型的常量,它只代表Drawable对象的ID,如果Java程序中需要获取实际的Drawable对象,则可调用Resources的getDrawable (int id)方法来实现。

2.Bitmap和BitmapFactory

Bitmap代表一个位图,BitmapDrawable里封装的图片就是一个Bitmap对象。

两者之间的转换:

//把一个Bitmap对象包装成BitmapDrawable对象
BitmapDrawable drawable = new BitmapDrawable (bitmap) ;

如果需要获取BitmapDrawable所包装的Bitmap对象,则可调用BitmapDrawable的getBitmap ()方法,如下面的代码所示:

//获取BitmapDrawable所包装的Bitmap 对象
Bitmap bitmap = drawable.getBitmap();

新建Bitmap对象的一些方法:

  • createBitmap (Bitmap source,int x, int y,int width,int height):从源位图source的指定坐标点(给定x、y)开始,从中“挖取"宽width、高height的一块出来,创建新的Bitmap对象。
  • createScaledBitmap (Bitmap class="lazy" data-src, int dstWidth,int dstHeight,boolean filter) :对源位图class="lazy" data-src进行缩放,缩放成宽dstWidth、高dstHeight的新位图。 filter是过滤器。
  • createBitmap (int width,int height,Bitmap.Config config):创建一个宽width、高height的新位图。
  • createBitmap (Bitmap source,int x, int y, int width,int height,Matrixm, boolean filter):从源位图source 的指定坐标点(给定x、y)开始,从中“挖取"宽 width、高height的一块出来,创建新的Bitmap对象,并按Matrix指定的规则进行变换。

Bitmap.Config类,在Bitmap类里createBitmap(int width, int height, Bitmap.Config config)方法里会用到,打开个这个类一看 :枚举变量

public static final Bitmap.Config ALPHA_8

public static final Bitmap.Config ARGB_4444

public static final Bitmap.Config ARGB_8888

public static final Bitmap.Config RGB_565

BitmapFactory是一个工具类,它提供了大量的方法,这些方法可用于从不同的数据源来解析、创建Bitmap对象。BitmapFactory包含了如下方法。

  • decodeByteArray (byte[]data,int offset,int length)︰从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象。
  • decodeFile (String pathName) :从pathName指定的文件中解析、创建Bitmap对象。
  • decodeFileDescriptor (FileDescriptor fd):用于从FileDescriptor对应的文件中解析、创建Bitmap对象。
  • decodeResource (Resources res,int id) :用于根据给定的资源ID从指定资源中解析、创建Bitmap对象。
  • decodeStream (InputStream is):用于从指定输入流中解析、创建Bitmap对象。

对于创建而言,对应的就是回收了。如果系统不停的去解析、创建Bitmap对象,可能由于创建的Bitmap所占用的内存还没回收,而导致OOM。

  • boolean isRecycled ():返回该Bitmap对象是否已被回收。
  • void recycle () :强制一个Bitmap对象立即回收自己。

如果Android应用需要访问其他存储路径(比如SD卡)里的图片,那么都需要借助于BitmapFactory来解析、创建Bitmap对象。

2.1 例子

下面开发一个查看/assets/目录下图片的图片查看器,当用户单击该按钮时程序会自动去搜寻/assets/目录下的下—张图片。此处不再给出界面布局代码,该程序的代码如下。

public class Test4Activity extends Activity {
    String[] images = null;
    AssetManager assets = null;
    int currentImg = 0;
    private ImageView image;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test4_acitvity);
        image = findViewById(R.id.test4_iv);
        Button next = findViewById(R.id.test4_bt_next);
        try {
            assets = getAssets();
            //获取assets目录目录下的所有文件
            images =assets.list("");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //按钮事件
        next.setOnClickListener(view -> {
            //如果发生数组越界
            if(currentImg >= images.length){
                currentImg = 0;
            }
            //找到下一个图片文件
            while (!images[currentImg].endsWith(".png")&&!images[currentImg].endsWith(".jpg")
                    &&!images[currentImg].endsWith(".gif")){
                currentImg++;
                //如果已经发生了数组越界
                if(currentImg >= images.length){
                    currentImg = 0;
                }
            }
            InputStream assetFile = null;
            try {
                //打开指定资源对应的输入流
                assetFile = assets.open(images[currentImg++]);
            } catch (IOException e) {
                e.printStackTrace();
            }
            BitmapDrawable bitmapDrawable = (BitmapDrawable) image.getDrawable();
            //如果图片还未回收,先强制回收该图片
            if(bitmapDrawable != null&&!bitmapDrawable.getBitmap().isRecycled()){
                bitmapDrawable.getBitmap().recycle();
            }
            //改变ImageView显示图片
            //调用了BitmapFactory从指定输入流解析并创建Bitmap
            image.setImageBitmap(BitmapFactory.decodeStream(assetFile));
        });
    }
}

2.2 额外知识点(assets)

系统为每一个新设计的程序提供了/assets文件夹,这个文件夹保存的文件能够打包在程序里。

/res和/assets的不同点是,android不为/assets下的文件生成ID。假设使用/assets下的文件,须要指定文件的路径和文件名称。怎样访问/assets下的内容?

例如,假设在assets目录下有一个名称为filename的文件,那么就可以使用以下代码来访问它:

AssetManager assset= getAssets();  
InputStream is = assset.open("filename");

2.3 代码更严谨

1.发现这代码一点黄色都没有,证明很严谨。

注意为什么button放在了里面,而imageView放在了外面。

将button放在外面会有Field can be converted to a local variable的警告,意思是检测到这个变量可以使用局部变量替换,建议删除并写成局部变量。就是其他地方也没有使用到它,没有必要声明成成员变量。

2.设计到数组访问,一定要防止其数组越界。上面还搞了两个。

assetFile = assets.open(images[currentImg++]);

此时进入到open的必定是图片资源的name,用了之后currentImg自加,探索下一个图片。第一个防止其数组越界的判断就是防这里的;第二是对应着判断不是图片资源的++。但是这个代码还有问题:假如里面有资源,但是都不是图片资源。那就会进入死循环

3.在显示图片之前,一定要释放之前的Bitmap,以免OOM

释放的判断的条件是使用Bitmap的封装类。

3.Android9新增的ImageDecoder

Android 9 引入了 ImageDecoder、OnHanderDecodedListener 等API,提供了更强大的图片解码支持,可以解码png、jpeg等静态图片和gif、webp等动画图片。另外。还新增了支持HEIF格式:

HEIF格式:这种压缩格式据有超高的压缩比例,相比JPEG,可以压缩到其一半大小,而且可以保证其近似的图片质量。

当使用 ImageDecoder 解码gif、webp等动画图片时,会返回一个AnimatedImageDrawable对象,调用AnimatedImageDrawable对象的start()方法即可开始执行动画。

ImageDecoder 解码图片的方式:

  • 调用 ImageDecoder 的重载的 createSource 方法来创建 Source 对象。根据不同的图片来源, createSource 方法有不同的重载模式。
  • 调用ImageDecoder 的 decodeDrawabIe(Source) or decodeBitmap(Source)方法来读取代表图片的 Drawable或 Bitmap对象。

在第二步时,可以额外传入一个OnHanderDecodedListener参数,该参数代表了监听器,该监听器要实现一个 onHanderDecoded(ImageDecoder,ImageInfo,Source)方法,可以对ImageDecoder进行额外的设置,也可以通过 ImageInfo 获取被解码图片的信息。

3.1 例子

public class Test5Activity extends AppCompatActivity {
    //说白了只有api 28 之后的才进的来
    @RequiresApi(api = Build.VERSION_CODES.P)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test5);
        //获取对象
        TextView textView = findViewById(R.id.test5_tv);
        ImageView imageView = findViewById(R.id.test5_iv);
        //创建 imageDecoder.Source对象
            //第一步:
            ImageDecoder.Source source = ImageDecoder.createSource(getResources(),R.drawable.viewgif);
            try {
                //第二步:执行decodeDrawable()方法获取Drawable对象
                @SuppressLint({"WrongThread", "SetTextI18n"})
                Drawable drawable = ImageDecoder.decodeDrawable(source,(decoder, info, s) ->{
                    //通过 info 参数获取被解码图片的信息
                    textView.setText("图片的原始宽度:"+info.getSize().getWidth()+
                            "\n"+"图片原始宽高"+info.getSize().getHeight());
                    //设置图片解码之后的缩放大小
                    decoder.setTargetSize(600,580);
                });
                imageView.setImageDrawable(drawable);
                //如果drawable 是AnimatedImageDrawable的实例,则执行动画
                if(drawable instanceof AnimatedImageDrawable){
                    ((AnimatedImageDrawable) drawable).start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

与传统的BitmapFactory相比,ImageDecoder 甚至可以解码包含不完整或错误的图片,如果希望显示ImageDecoder解码出错之前的部分图片,则可通过为 ImageDecoder没置OnPartialImageListener监听器来实现。例如如下代码片段:

//先用Lambda 表达式作为OnHeaderDecodeListener监听器
    Drawable drawable = ImageDecoder.decodeDrawable(source,(decoder, info, s) ->{
        //为ImageDecoder 设置 OnPartialImageListener 监听器(Lambda 表达式)
        decoder.setOnPartialImageListener(e->{
            ....
            //return true 表明即使不能完整地解码全部图片也返回Drawable或Bitmap
            return true;
        });
    });

到此这篇关于Android自定义视图中图片的处理的文章就介绍到这了,更多相关Android图片内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android自定义视图中图片的处理

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android自定义ProgressDialog加载图片

为了提高用户体验,我们肯定希望该Dialog能更加炫酷,让用户看着更舒服。那如何做呢,当然是我们自己定义一个ProgressDialog了。一、使用系统加载框mDialog = new ProgressDialog(this); mDial
2022-06-06

Android如何自定义视图属性

本文实例为大家介绍了Android自定义视图属性的方法,供大家参考,具体内容如下 1. 自定义一个自己的视图类继承自Viewpublic class MyView extends View {public MyView(Context co
2022-06-06

Android App中自定义View视图的实例教程

一、基础 很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章。先总结下自定义View的步骤: 1、自定义View的属性
2022-06-06

android自定义ImageView仿图片上传示例

看下效果图主要看下自定义view 代码public class ProcessImageView extends ImageView{ private Context context; private Paint paint; privat
2022-06-06

Android自定义EditText右侧带图片控件

前言最近项目做用户登录模块需要一个右边带图片的EditText,图片可以设置点击效果,所以就查资料做了一个自定义EditText出来,方便以后复用。 原理下面是自定义EditText的代码,具体难点是要实现图片的点击监听,因为谷歌官方至今没
2022-06-06

Android自定义图片地图坐标功能的实现方法

本篇内容主要讲解“Android自定义图片地图坐标功能的实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android自定义图片地图坐标功能的实现方法”吧!一、前言最近项目要求实现一个在自
2023-06-20

Android中自定义加载样式图片的具体实现

先让大家看看效果图吧,相信很多Android初学者都想知道这中效果是怎么实现的,来上图: 想实现上面这张图中的自定义加载样式,其实很简单,首先我们需要的布局组件有ProcessBar和TextView,下面是布局文件的代码(只是加载的页面的
2022-06-06

Android自定义组件获取本地图片和相机拍照图片

iOS中有封装好的选择图片后长按出现动画删除效果,效果如下 而Android找了很久都没有找到有这样效果的第三方组件,最后懒得找了还是自己实现这效果吧 选择图片后还可对图片进行剪裁 当然,代码中还有很多不完善的地方,我接下来会继续完善这个
2022-06-06

Android使用xml自定义图片实例详解

Android使用xml自定义图片实例详解实现效果图:白色圆角图片bg_round_rectangle_white.xml2023-05-31

Android应用开发中自定义ViewGroup视图容器的教程

一、概述 在写代码之前,我必须得问几个问题: 1、ViewGroup的职责是啥? ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性,都是为用于告诉容器的),我们的宽度(
2022-06-06

Android自定义ImageView实现在图片上添加图层效果

首先我们先看下效果图实现思路 这是两张前后对比图,右边第二张图里面的已抢光标签图片当已经没有商品的时候就会显示了,在每个图片的中心位置,第一想法是在ImageView的外层再套一层RelativeLayout 实现方法
2022-06-06

Android开发之自定义View(视图)用法详解

本文实例讲述了Android开发之自定义View(视图)用法。分享给大家供大家参考,具体如下: View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。在游戏开发
2022-06-06

自定义视图view的折线图使用讲解

这篇文章主要介绍了自定义视图view的折线图使用讲解,前面几章讲解了绘图的一些基本用法,本章就来看看折线图吧,需要的朋友可以参考下
2023-05-14

自定义视图view的折线图怎么使用

这篇文章主要讲解了“自定义视图view的折线图怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“自定义视图view的折线图怎么使用”吧!绘制折线图预览图绘制这个折线图需要都需要哪些步骤?
2023-07-05

Android自定义View实现多图片选择控件

前言 相信很多朋友在开发中都会遇到图片上传的情况,尤其是多图上传,最经典的莫过于微信的图片选择了。所有很多情况下会使用到多图选择,所以就有了这篇文章,今天抽点时间写了个控件。 支持自定义选择图片的样式 支持设置图片选择数量 支持图片预
2022-06-06

Android实现自定义轮播图片控件示例

要完成一个轮播图片,首先想到的应该是使用ViewPager来实现。ViewPager已经有了滑动的功能,我们只要让它自己滚动。再加上下方的小圆点就行了。所以我们本次的自定义控件就是由ViewPager和LinearLayout叠加起来组成的
2022-06-06

Android实现自定义轮播图片控件详解

首先上效果图实现原理 要完成一个轮播图片,首先想到的应该是使用ViewPager来实现。ViewPager已经有了滑动的功能,我们只要让它自己滚动。再加上下方的小圆点就行了。所以我们本次的自定义控件就是由ViewPager和LinearLa
2022-06-06

自定义视图View绘图基础之Path的使用

这篇文章主要介绍了自定义视图View绘图基础之Path的使用,path类是一个非常有用的类,他可以预先在view上讲N个点连成一条“路径”,然后调用Canvas的drawPath(path,paint)即可沿着路径绘制图形,需要的朋友可以参考下
2023-05-14

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录