Android的三种图片加载(ImageView,SufaceView,自定义View)

Android显示系统(03)- OpenGL ES - GLSurfaceView的使用 我们应用层和Native层其实都可以直接调用EGL接口或者OpenGL ES的接口,但是,可能比较复杂一些,Android提供了更加方便的类供应用开发者使用,会在自己的渲染线程GLThread启动之后创建OpenGL ES环境。 阅读详情

最近看了音视频的入门,所以对着三种加载图片的方式自己动手实现了一下,下面就是自己实现的过程还有我在实现种所处理的问题:

MainActivity种的代码:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private ImageView iv;
    private SurfaceView sfView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);

        sfView = (SurfaceView) findViewById(R.id.sf_view);
        /**
         * 三种加载图片的方式
         */
        initSetImageView();

        initSetSufaceView();

        initSetMyView();
    }

    /**
     * 使用自定义View的形式设置图片
     */
    private void initSetMyView() {

    }

    /**
     * 使用SufaceView设置图片
     */
    private void initSetSufaceView() {
        sfView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if (holder == null) {
                    return;
                }

                Paint paint = new Paint();
                //设置抗锯齿
                paint.setAntiAlias(true);
                //设置填充样式
                paint.setStyle(Paint.Style.STROKE);

                //获取Bitmap
                Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()
                        .getPath() + File.separator + "test.jpg");


                int width = bitmap.getWidth();
                int height = bitmap.getHeight();

                holder.setFixedSize(width, height);

                //锁定画布
                Canvas canvas = holder.lockCanvas();

                //设置画布背景,他主要是绘制了两次,盖在上面而已,并不是设置背景,
                // 所以要将它提到绘制操作的前面
                canvas.drawRGB(0, 0, 0);

                //执行绘制操作
                canvas.drawBitmap(bitmap, 0, 0, paint);

                //解除画布
                holder.unlockCanvasAndPost(canvas);

            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
    }

    /**
     * 使用ImageView设置图片(加读文件夹的权限)<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
     */
    private void initSetImageView() {
        //Environment.getExternalStorageDirectory()获取SD卡的绝对路径
        //    /storage/emulated/0这个就是手机里面的文件管理,不必再找文件夹里面的这个地址。
        //File.separator代表地址后面的单斜线或者双斜线,用作兼容功能,因为
        // windows和linux的格式不一样。
        //为什么要用这种模式拼接地址呢,因为可变性较高,可以随意配置
        Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()
                .getPath() + File.separator + "test.jpg");
        //设置Bitmap地址
        iv.setImageBitmap(bitmap);
    }
}

我首先先把代码粘出来,然后我来拆分一些我遇到的问题,在使用ImageView设置图片的时候,因为我的本地文件夹外层没有图片,所以在我使用这个方法的时候:

Environment.getExternalStorageDirectory().getPath()

却把图片保存进了双层相同地址中,导致一时没有获取图片的实例,bitmap一直为空(解决)

在用SufaceView设置图片的时候,发现他和自定义View一样,也是通过绘制进行图片显示的,而且他的显示方式是通过锁定画布和解锁画布来进行显示,这个时候,我并没有发现什么问题,但是,我的布局,这时候出现了一点点的毛病,请看我的主布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <SurfaceView
        android:id="@+id/sf_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.zhongjiao.com.drawpictures.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

按道理来说应该是三张图片排下来对叭,我也认为这样,但是呢,在我实现第三种情况,自定义View显示图片的时候,问题出现了···我们先看下自定义View里面的代码块:

public class CustomView extends View {
    Bitmap bitmap;
    //初始化画笔
    Paint paint = new Paint();

    public CustomView(Context context) {
        super(context);
        init(context, null);

    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        //设置抗锯齿
        paint.setAntiAlias(true);
        //设置样式
        paint.setStyle(Paint.Style.FILL_AND_STROKE);

        //获取Bitmap
        bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()
                .getPath() + File.separator + "test.jpg");
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取控件的宽高样式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width;
        int height;

        // 判断是否是wrap_content
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            width = Math.min(bitmap.getWidth(), widthSize);
        } else {
            width = bitmap.getWidth();
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            height = Math.min(bitmap.getHeight(), heightSize);
        } else {
            height = bitmap.getHeight();
        }
        //设置控件大小
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (bitmap != null) {
            //设置绘制图片的位置和参数
            canvas.drawBitmap(bitmap, 0, 0, paint);
        }
    }
}

这个里面是没有问题的,但是呢,,,,我的App运行起来却一直不显示自定义View的图片,这就让我很纳闷,,不应该啊,我这代码没毛病啊···然后我就各种排查我自定义View的问题,,直到,,我突然想起来,,会不会是SurfaceView把他盖住了??然后我就去xml里面吧他俩掉个位置,发现出现了三张图片···我特么,,虽然结果出来了,但是应该要去处理这个问题呀,然后我就看这个SurfaceView在布局里面设置大小都不好使,那只能在代码里面设置了,因为自定义View能动态控制控件大小,那么他肯定也可以,于是:

                int width = bitmap.getWidth();
                int height = bitmap.getHeight();

                holder.setFixedSize(width, height);

就在里面设置了这个,,这样问题就完美解决啦,三种加载方式无论怎么掉位置,都不会去影响图片的显示啦!

虫虫

Android Camera系列(三):GLSurfaceView+Camera 介绍了如何用GLSurfaceView预览Camera数据的流程。我们没有对opengl的API进行过多的讲解,以及Renderer接口是如何将数据渲染到中的。在后续的章节我会讲解opengl在Android中的使用,希望聪明的你在回看该章会有种醍醐灌顶的感觉吧 阅读详情

相关推荐

OpenCV透视变换原理与实战:从单应性矩阵到文档矫正

透视变换是计算机视觉中实现平面图像几何校正的基础技术,其核心在于利用单应性矩阵(Homography)建模三维空间到二维图像的射影关系。不同于仿射变换的线性约束,透视变换通过有理函数映射支持任意凸四边形间的非线性变形,天然适配真实场景中的远小近大、平行线汇聚等透视现象。该技术具备确定性强、计算高效、无需训练数据等工程优势,广泛应用于文档扫描矫正、车牌识别预处理、AR贴图对齐及无人机正射影像生成等场景。结合OpenCV的cv2.findHomography与cv2.warpPerspective接口,开发者可

weixin_30873847的博客 653

Android ImageView、TextureView、自定义View显示图片

ImageView 显示图片 在 Android 平台上,显示图片的方式有很多种,其中最为简单的就是 ImageView。 1 . 在 lyaout 布局中,声明好 ImageView &amp;amp;amp;amp;lt;ImageView android:id=&amp;amp;amp;quot;@+id/image_view&amp;amp;amp;quot; android:layout_width=&amp;amp;amp

三木仔 7942

第十二节:C#工业控制编程基础--输出正弦波实验

第十二节:基于c#使用开发板输出正弦波实验 文章目录第十二节:基于c#使用开发板输出正弦波实验一、实验目的:了解采集卡DA相关函数的使用。二、实验内容:利用C#生成正弦波,然后用采集卡DA输出。三、实验步骤:1.打开Visual Studio 2013,新建窗体应用程序项目,配置好板卡dll文件。2.在窗体中放入控件,对控件进行布局排版,并修改他们的Name属性和Text属性。3.在Chart控件内选择Spline型图表,如图2。4.进入编程区域,在public partial class Form1 :

weixin_49237052的博客 2295

【HDR学习】利用SurfaceView显示图片

但它也有缺点,因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以。SurfaceView属于View的子类它是专门为制作游戏而产生的,它的功能非常强大,最重要的是它支持OpenGL ES库,2D和3D的效果都可以实现。创建SurfaceView的时候需要实现SurfaceHolder.Callback接口,它可以用来监听SurfaceView的状态,比如:SurfaceView的改变 、SurfaceView的创建 、SurfaceView 销毁等。

cocoduco的博客 952

Zotero搭配CNKI.js插件:一键批量下载知网文献的完整教程(附常见问题解决)

本文提供Zotero搭配CNKI.js插件实现知网文献批量下载的完整教程。详细介绍了从环境准备、插件安装到实战操作的全流程,并针对常见问题提供解决方案,旨在帮助科研人员高效构建自动化文献管理工作流,显著提升文献收集与整理效率。

e4f5g6h7的博客 1200

智能体在车联网中的应用:一份详尽到每日的100天学习路线图

这100天的旅程,是一次对毅力、学习方法和工程实践能力的综合考验。它不仅关乎掌握一系列技术点,更关乎培养解决复杂系统性问题的思维模式——将宏观的交通需求分解为微观的智能体决策,再通过多智能体协同涌现出宏观的智能行为。当你完成这份大纲时,你将拥有的不仅是一个项目作品集,更是一套应对“智能体+车联网”乃至更广泛AI+垂直领域挑战的方法论。未来已来,期待你成为构建智能交通新生态的关键贡献者。

IT深耕十余载,大道之简 1332

基于 FFmpeg 的跨平台视频播放器简明教程(十二):Android SurfaceView 显示图片和播放视频

上一章中我们介绍了一个简易的播放器架构,对之前零碎的代码片段进行了组织和重构,形成了较为灵活的一种架构设计,它非常简单,但足够满足我们的需求。现在,接着我们在 Android 上的旅程。今天我们来讨论如何在 Android 上显示画面。Android 原生的 Java/Kotlin 接口播放视频还是很容易的,有 MediaController、MediaPlayer 等类可以直接使用,相关教程参考Android实现视频播放的3种实现方式。

记录学习的过程 1347

【用unity实现100个游戏之19】制作一个3D传送门游戏,实现类似鬼打墙,迷宫,镜子,任意门效果(附项目源码)

本文介绍了Unity中实现传送门效果的完整流程。通过第一人称角色控制器实现移动,使用PortalView脚本和自定义Unlit Shader渲染门内场景,巧妙利用相机位置和旋转同步实现动态视角。重点解决了近裁剪面问题,确保远距离渲染正确性。最后通过PortalTeleporter脚本实现传送功能,检测碰撞并计算相对位置进行瞬移。该方法无需复杂插件,代码简洁高效,适用于各类3D场景中的传送门实现。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1万+

基于SurfaceView创建手机xml动态背景

surfaceView通俗的讲就类似与给手机的那层薄膜,在那层薄膜上你可以绘制各种图画甚至动画,我写了一个关于利用surfaceView铺设了一个“膜”,在使用MediaPlayer调用播放短视频来实现背景为动态背景的效果,话不多说直接进入代码之中: 新建一个java类,用于设置这层“薄膜”,起名为MySurfaceView继承SurfaceView类: package com.sq.te

帅帅小强哥的博客 789

数学建模学习(78):多输入多输出回归预测模型(结合XGBoost实现)

多输入多输出回归预测问题求解

全栈川川 8130

FPGA设计-Vivado的Off-Chip Termination设置问题

经常遇到在FPGA设计时,很多人很迷惑这些关于硬件的终端匹配怎么设置,Vivado的Off-Chip Termination设置问题,这里就详细说一下这个问题。

whm128的博客 2723

自定义SurfaceView加载图片

想用surfaceView去加载一张静态图片。网上查了半天很多都是没有效果的。最后自己研究了一下。可以加载图片了。 package com.showly.autopollrecyclerviewdemo.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import and

huyawenz的博客 2601

【雷达】一维和二维自适应波束形成(DBF))DBF附matlab代码

1 简介 数字波束形成技术是天线波束形成原理与数字信号处理技术相结合的产物,其广泛应用于阵列信号处理领域.由于电磁工作环境的恶化和大量射频干扰的存在,在极低的信干噪比(SINR)条件下进行目标检测和信息提取十分困难.对于阵列系统,往往采用自适应数字波束形成(ADBF)技术,来抑制强干扰和方向性干扰对有用信号的影响.介绍了数字波束形成器的基本原理及其DSP的实现结构.​ 2 完整代码 clc;clear all;close all;%%%%%%%%%%%%%%%%%一维DBF%%%%%%%%%%%%%

qq_59747472的博客 7265

SurfaceView高性能绘制(零)SurfaceView简单绘制图片

一、SurfaceView绘制图片 主要代码 surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { if (h...

鲁迷那的专栏—坚持实践后再写出来! 3942

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

SurfaceView作为底层,控件平移后,被遮挡的解决办法

最近在做视频录像的一个小功能,功能不多,就录像,保存,取消。界面类似微信那样。 界面是这样的,额,因为UI没给我图,右上角是切换摄像头,指纹那里是长按录像。松开录制结束,会出现两个按钮,位置和录像按钮一样,然后动画平移至两边,再把录像隐藏          在界面上就类似这种效果,动画也比较简单。上界面代码,代码都比较简单,可以跳过 &lt;?xml version="1.0" en...

qq_27454233的博客 5176

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【源码】让源码告诉你:为什么在子线程无法更新 UI 操作?

博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载。本文由博主威威喵原创,请多支持与指教。 本文首发于此 博主:威威喵|博客主页:https://blog.youkuaiyun.com/smile_running 直接步入主题,今天我们来讲讲为什么在子线程无法更新 UI,这也是困扰我很久的一个问题,在我初学 Android 的那个时候,特别是在学习 Android ...

你若盛开,蜜蜂自来 8375

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

android surfaceview 显示图片_Android 零基础学相机,音视频开发。

该文章由公众号「aserbaocool」赞助。如需转载请联系公众号作者。如果你有学Android 音视频,相机开发的想法,那么这篇文章可以作为一篇不错的参考文章。当然本文为付费文章,收费5元,如果对你有用,文末赞赏缴费即可。如果没有学习音视频,相机的欲望,赶快走,赶快走,不要有一丝停留,因为这篇文章确实枯燥无味且毫无快感可言。请考虑3s赶快决定去留。321我再扯两句:这篇是在学习相机音视频开发的时...

weixin_39646018的博客 1773

关于SurfaceView中不能完全显示整张图片的问题

前些天朋友用surfaceView组件显示图片时遇到只能显示半张图片问题。一开始我以为图片过大,于是换了张小图片试试,结果小图片只显示在surfaceView的一角,其他部分为surfaceView的黑色部分。 经过我的分析研究对图片进行了缩放,废话少说,下面介绍一下我的方法。

renzaijianghu12354的专栏 2260

使用SurfaceView加载多张大分辨率图片做帧动画,解决OOM问题

项目需求:动态背景 需求很简单,只是用帧动画做一个动态的背景而已,但若是70多张图片都是1920*1080,一张485k的话,传统意义上的帧动画就很难实现了,往往加载10张就开始OOM。 一般来说,常用的实现动态背景的有效方式有三种: ①视频:果断粗暴,清晰度很有保证,但是在无限轮播重复的时候,总会有一瞬间的卡顿,这真的很让人郁闷。 ②GIF动态图:直接

Giousa的博客 4900

从显示一张图片开始学习OpenGL ES

前言 网上很多介绍OpenGL ES的文章,但由于OpenGL ES内容太多,所以这些文章难免过于臃肿杂乱,很难抓住重点,对于初学者来说最后还是云里雾里。很多人(包括笔者本人)开始深入了解OpenGL ES是因为其涉及到实时滤镜的应用,通常都会参考开源框架GPUImage的实现。如果没有掌握基本的OpenGL Es的开发知识,很难弄懂其中代码缘由。 目前很流行的短视频特效处理也有涉及到OpenGL...

weixin_34082695的博客 834

Android图像渲染:SurfaceView与GLSurfaceView多格式图片加载实现方案

摘要: 本文对比了Android开发中SurfaceView和GLSurfaceView两种图像渲染方案。SurfaceView通过OpenCV实现多格式图片(灰度图、BGR、YUV420等)转换,但存在帧率不稳(30fps时单帧耗时50-80ms)和CPU占用高(达70%)的问题。GLSurfaceView利用GPU加速显著提升性能。详细给出了SurfaceView的实现步骤:①OpenCV环境初始化;②SurfaceHolder生命周期管理;③建立阻塞队列控制内存;④OpenCV格式转换(如YUV420

wolf0706的专栏 1680

王学岗——————Opengl加载图片以(对应第34节课)

用openGL加载图片

qczg_wxg的博客 1740

Android利用SurfaceView显示Camera图像爬坑记(一)

前排

Misdirection_XG的博客 645

解决surfaceview滑动闪烁黑屏

当多个surfaceview之间滑动的时候,两个view之间会有黑线。这是用于surfaceview的双缓存机制引起。之前想了好多方法都想不通。最后终于想到了一个妥协的办法。 就是将surfaceview的背景色设置为要绘制图形的背景色(或者是将绘制的图片设置为背景) setBackgroundColor(Color.argb(255,255,231,115)); 复

shadowliucs的专栏 2719

Android 屏幕截图黑屏问题解决方法

以下两种截屏方法可能由于尺寸没有设置默认过大系统不予处理。 public static Bitmap convertViewToBitmap(View view, int bitmapWidth, int bitmapHeight){ Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Con

icy_xm的专栏 9673
上一篇: Android 如何适配平板
下一篇: kotlin实现底部导航栏
四块五毛六
博客等级 码龄9年 43粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值