当前位置:

首页 > 系统应用 > 8.2.1 Bitmap(位图)全解析 Part 1

8.2.1 Bitmap(位图)全解析 Part 1

本文目录

    本节引言: 在上一节中我们对Android中的13种类型的Drawable的类型进行了讲解,有没有应用到自己的 项目当中呢?而本节我们来探讨的是Bitmap(位图)的一些使用,而在开始本节的内容之前我们 先来区分几个名词的概念: Drawable:通用的图形对象,用于装载常用格式的图像,既可以是PN

    本节引言:

    在上一节中我们对Android中的13种类型的Drawable的类型进行了讲解,有没有应用到自己的 项目当中呢?而本节我们来探讨的是Bitmap(位图)的一些使用,而在开始本节的内容之前我们 先来区分几个名词的概念:

    • Drawable:通用的图形对象,用于装载常用格式的图像,既可以是PNG,JPG这样的图像, 也是前面学的那13种Drawable类型的可视化对象!我们可以理解成一个用来放画的——画框!
    • Bitmap(位图):我们可以把他看作一个画架,我们先把画放到上面,然后我们可以 进行一些处理,比如获取图像文件信息,做旋转切割,放大缩小等操作!
    • Canvas(画布):如其名,画布,我们可以在上面作画(绘制),你既可以用Paint(画笔), 来画各种形状或者写字,又可以用Path(路径)来绘制多个点,然后连接成各种图形!
    • Matrix(矩阵):用于图形特效处理的,颜色矩阵(ColorMatrix),还有使用Matrix进行图像的 平移,缩放,旋转,倾斜等!

    而上述的这些都是Android中的底层图形类:android.graphics给我们提供的接口! 嗯,话不多说开始本节内容! PS:官方文档:Bitmap

    1.了解Bitmap,BitmapFactory,BitmapFacotry.Options

    如题,本来可以直接说着三个东东的关系的,但是我就是要傲娇,就要看代码! 如果你打开Bitmap类的源码,你会看到Bitmap的构造方法上有这样一段东东:

    这段内容其实不复杂,核心就一句话:Bitmap 的构造方法是私有的,外部没法直接 new,只能借助 JNI 来完成实例化。
    不过也不用担心,系统早就把入口准备好了,专门负责创建 Bitmap 的接口类就是:BitmapFactory。
    接着把 BitmapFactory 类打开,再点一下左侧的 Structure,就能看到它提供的一整套方法。你会发现,里面大多数都是 decodeXxx,本质上就是通过不同的输入形式,把 Bitmap 创建出来。

    接着我们又发现了,每一种方法,都会有一个Options类型的参数,点进去看看: 于是乎我们发现了这货是一个静态内部类:BitmapFacotry.Options! 而他是用来设置decode时的选项的!

    我们对这里的某些参数的值进行设置,比如inJustDecodeBounds设置为true避免OOM(内存溢出), 什么,不知道OOM,没事,等下一点点跟你说清楚!最后回到我们的Bitmap!嗯,Bitmap中的 方法比较多,就不一一进行讲解了,我们从中挑几个用得较多的来讲解! 中文文档:Android中文API(136) —— Bitmap

    2.Bitmap常用方法

    普通方法

    • public boolean compress (Bitmap.CompressFormat format, int quality, OutputStream stream) 将位图的压缩到指定的OutputStream,可以理解成将Bitmap保存到文件中! format:格式,PNG,JPG等; quality:压缩质量,0-100,0表示最低画质压缩,100最大质量(PNG无损,会忽略品质设定) stream:输出流 返回值代表是否成功压缩到指定流!
    • void recycle():回收位图占用的内存空间,把位图标记为Dead
    • boolean isRecycled():判断位图内存是否已释放
    • int getWidth():获取位图的宽度
    • int getHeight():获取位图的高度
    • boolean isMutable():图片是否可修改
    • int getScaledWidth(Canvas canvas):获取指定密度转换后的图像的宽度
    • int getScaledHeight(Canvas canvas):获取指定密度转换后的图像的高度

    静态方法:

    • Bitmap createBitmap(Bitmap src):以src为原图生成不可变得新图像
    • Bitmap createScaledBitmap(Bitmap src, int dstWidth,int dstHeight, boolean filter):以src为原图,创建新的图像,指定新图像的高宽以及是否变。
    • Bitmap createBitmap(int width, int height, Config config):创建指定格式、大小的位图
    • Bitmap createBitmap(Bitmap source, int x, int y, int width, int height)以source为原图,创建新的图片,指定起始坐标以及新图像的高宽。
    • public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)

    BitmapFactory.Option可设置参数:

    • boolean inJustDecodeBounds——如果设置为true,不获取图片,不分配内存,但会返回图片的高宽度信息。
    • int inSampleSize——图片缩放的倍数。如果设为4,则宽和高都为原来的1/4,则图是原来的1/16。
    • int outWidth——获取图片的宽度值
    • int outHeight——获取图片的高度值
    • int inDensity——用于位图的像素压缩比
    • int inTargetDensity——用于目标位图的像素压缩比(要生成的位图)
    • boolean inScaled——设置为true时进行图片压缩,从inDensity到inTargetDensity。

    好吧,就贴这么多吧,要用自己查文档~

    3.获取Bitmap位图

    从资源中获取位图的方式有两种:通过BitmapDrawable或者BitmapFactory,下面演示下: 我们首先得获得这个

    BitmapDrawable方法:

    你可以创建一个构造一个BitmapDrawable对象,比如通过流构建BitmapDrawable:

    BitmapDrawable bmpMeizi = new BitmapDrawable(getAssets().open("pic_meizi.jpg"));
    Bitmap mBitmap = bmpMeizi.getBitmap();
    img_bg.setImageBitmap(mBitmap);

    BitmapFactory方法:

    都是静态方法,直接调,可以通过资源ID、路径、文件、数据流等方式来获取位图!

    //通过资源ID
    private Bitmap getBitmapFromResource(Resources res, int resId) {
          return BitmapFactory.decodeResource(res, resId);
    }
    //文件
    private Bitmap getBitmapFromFile(String pathName) {
          return BitmapFactory.decodeFile(pathName);
    }
    //字节数组
    public Bitmap Bytes2Bimap(byte[] b) {
        if (b.length != 0) {
            return BitmapFactory.decodeByteArray(b, 0, b.length);
        } else {
            return null;
        }
    }
    //输入流
    private Bitmap getBitmapFromStream(InputStream inputStream) {
          return BitmapFactory.decodeStream(inputStream);
    }

    4.获取Bitmap的相关信息:

    这个,只要我们获取了Bitmap对象,就可以调用相关方法来获取对应的参数了,getByteCount获得大小, getHeight和getWidth这些~这里就不写了,自己查文档!

    5.抠图片上的某一角下来

    有时,可能你想把图片上的某一角扣下来,直接通过Bitmap的createBitmap()扣下来即可 参数依次为:处理的bitmap对象,起始x,y坐标,以及截取的宽高

    Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.pic_meizi);
    Bitmap bitmap2 = Bitmap.createBitmap(bitmap1,100,100,200,200);
    img_bg = (ImageView) findViewById(R.id.img_bg);
    img_bg.setImageBitmap(bitmap2);

    运行效果图:

    原图:

    切下来的一角:

    6.对Bitmap进行缩放

    我们这里不用Matrix来对Bitmap,而是直接使用Bitmap给我们提供的createScaledBitmap来实现, 参数依次是:处理的bitmap对象,缩放后的宽高,

    7.使用Bitmap进行截屏

    运行效果图:

    实现代码:

    public class MainActivity extends AppCompatActivity {
        static ByteArrayOutputStream byteOut = null;
        private Bitmap bitmap = null;
        private Button btn_cut;
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            btn_cut = (Button) findViewById(R.id.btn_cut);
            btn_cut.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    captureScreen();
                }
            });
        }
    public void captureScreen() {
            Runnable action = new Runnable() {
                @Override
                public void run() {
                    final View contentView = getWindow().getDecorView();
                    try{
                        Log.e("HEHE",contentView.getHeight()+":"+contentView.getWidth());
                        bitmap = Bitmap.createBitmap(contentView.getWidth(),
                                contentView.getHeight(), Bitmap.Config.ARGB_4444);
                        contentView.draw(new Canvas(bitmap));
                        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteOut);
                        sa vePic(bitmap, "sdcard/short.png");
                    }catch (Exception e){e.printStackTrace();}
                    finally {
                        try{
                            if (null != byteOut)
                                byteOut.close();
                            if (null != bitmap && !bitmap.isRecycled()) {
    //                            bitmap.recycle();
                                bitmap = null;
                            }
                        }catch (IOException e){e.printStackTrace();}
    }
                }
            };
            try {
                action.run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    private void sa vePic(Bitmap b, String strFileName) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(strFileName);
                if (null != fos) {
                    boolean success= b.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    fos.flush();
                    fos.close();
                    if(success)
                        Toast.makeText(MainActivity.this, "截屏成功", Toast.LENGTH_SHORT).show();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    代码分析:

    代码非常简单,final View contentView = getWindow().getDecorView();这句代码是获取当前XML 根节点的View!然后设置截屏的大小,调用下contentView.draw(new Canvas(bitmap));好了,然后 bitmap转换成流,接着写入SD卡,没了~当然从结果我们也可以看出,截图截取的是改APP的内容而已! 如果要截全屏,自行谷歌~!

    本节小结:

    这一节主要梳理Bitmap、BitmapFactory及其静态内部类Options,还有BitmapDrawable的基础用法。说得直接一点,Bitmap本身先把创建方式吃透,基本就够用了;至于它的扩展能力,更多还是借助Matrix和Canvas来完成。实际开发里,围绕Bitmap最需要盯紧的,往往不是“会不会用”,而是OOM这类内存问题。下一节就接着看,Bitmap的OOM到底该怎么规避。

    本文内容来源于网友投稿,如有侵权请联系删除。
    作者最新文章
    系统应用
    相关文章 更多
    docker容器自动重启怎么解决 排查原因与修复方法
    docker容器自动重启怎么解决 排查原因与修复方法

    遇到Docker容器频繁自动重启?本文提供从查看容器日志、解读退出代码到配置Restart Policy的完整排查与修复方案,确保服务稳定性。

    Linux设置静态路由命令与永久生效教程
    Linux设置静态路由命令与永久生效教程

    学习如何在Linux中使用命令行添加临时静态路由,并通过修改网络配置文件实现重启后依然有效的永久静态路由设置,涵盖CentOS和Ubuntu的不同配置方法。

    摄像头连接电脑后怎么打开查看实时画面教程
    摄像头连接电脑后怎么打开查看实时画面教程

    摄像头连接电脑后不知如何查看画面?本教程演示如何使用Windows自带的“相机”应用快速调取实时视频流,无需下载额外软件,步骤简单直观,适用于大多数USB及内置摄像头。

    如何在 windows 11 关闭自动关机
    如何在 windows 11 关闭自动关机

    针对 Windows 11 电脑在无人操作时自动关机或重启的问题,本文详解如何通过任务计划程序禁用更新重启任务,并调整电源睡眠策略,从根源解决非预期的自动关机现象。

    电脑摄像头怎么测试人脸识别功能及效果判断方法
    电脑摄像头怎么测试人脸识别功能及效果判断方法

    详细讲解在Windows电脑上测试摄像头人脸识别功能的步骤,包括开启Windows Hello、录入面部数据、不同环境下的效果验证及常见问题排查,帮助用户确认设备兼容性与识别准确率。

    docker 容器无法启动的配置检查命令及排查方法
    docker 容器无法启动的配置检查命令及排查方法

    当 Docker 容器启动后立即退出时,不要盲目重启。本文详解如何通过 docker logs 查看标准输出错误,利用 docker inspect 检查挂载与网络配置,并修正入口点脚本权限问题,提供一套高效的因果排查流程。

    安卓手机投屏到电脑win10怎么设置教程
    安卓手机投屏到电脑win10怎么设置教程

    详解如何利用Windows 10自带功能将安卓手机画面投射至电脑屏幕,涵盖开启步骤、连接技巧及延迟分析,适合临时演示与多屏协作场景。

    移动硬盘解除加密怎么操作?详细步骤教程
    移动硬盘解除加密怎么操作?详细步骤教程

    详细介绍如何在Windows系统中为移动硬盘解除BitLocker加密,包括解锁驱动器、关闭加密功能及监控解密进度的完整操作流程,帮助用户安全移除数据保护。

    笔记本电脑耳机没声音怎么设置?Windows 10解决方法
    笔记本电脑耳机没声音怎么设置?Windows 10解决方法

    本文详解Windows 10笔记本耳机无声音的常见原因与解决方法,涵盖物理接口检查、默认播放设备切换、驱动程序更新及音频增强关闭等操作,并分析蓝牙耳机连接异常的例外场景。

    sata固态硬盘安装win10系统怎么分区详细教程
    sata固态硬盘安装win10系统怎么分区详细教程

    还在为SATA固态硬盘装Win10怎么分区头疼?本教程详解安装过程中的分区步骤,涵盖4K对齐检查、ESP引导分区处理及容量规划建议,助你一次性搞定系统盘,避免后期卡顿与空间浪费。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    WINDOWS 更多
    3dmax(3ds max)
    3dmax(3ds max)
    Windows

    Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。