55. 【Android教程】位图:Bitmap

在上一节学习 Drawable 图像资源的时候我们在很多地方用到了 bitmap,bitmap 其实就是真实图片在 Android 中最直接的表现形式,这一节我们来仔细学习一下 Bitmap 的使用。

1. 什么是 Bitmap

Bitmap 在 Android 中对应一张图片文件,它是一个二位系统,通过编码记录了一张图片的完整形式。以左上角为原点,向右和向下建立一个(X , Y)坐标系,坐标系中的每一个点都成为一个“像素”。在不同编码格式的 Bitmap 里一个像素占的 bit 数有所不同,这些 bit 共同表征了当前像素的色值,可能是8 bit、16 bit 或者 24 bit 等等,最后将这些所有的色值组合起来就成了一张完整的原始图片。

我们在 Android 中绘制的一切图像都是一个 Bitmap,我们可以创建一个 Bitmap 示例或者使用 Bitamp 工具来修改、优化一个图像资源。

2. Bitmap 的常用 API

  • createBitmap(int width, int height, Bitmap.Config config):
    根据传入的宽高、创建一个可修改的 Bitmap 对象
  • createBitmap(DisplayMetrics display, int width, int height, Bitmap.Config config):
    相比上一个接口,这个可以在创建的时候传入一些参数
  • createBitmap(Bitmap src):
    根据传入的 Bitamp 创建一个新的 Bitamp
  • copy(Bitmap.Config config, boolean isMutable):
    将 Bitamp 对象的所有像素复制到一个新的 Bitmap 当中
  • extractAlpha():
    提取原始 Bitmap 的透明度并返回一个新的 Bitamp
  • getConfig():
    获取 Bitamp 的配置信息
  • getDensity():
    返回 Bitamp 的图片像素密度
  • getRowBytes():
    返回 Bitamp 图片的像素字节数组
  • setPixel(int x, int y, int color):
    设置图片的(x, y)坐标点上的色值
  • setDensity(int density):
    设置图片像素密度

3. 获取 Bitamp 实例

Android 提供了多种方法获取 Bitamp 实例,我们可以直接从 ImageView 上拿到当前设置的图片的 Bitamp 对象:

private Bitmap bmp;
private ImageView img;
img = (ImageView)findViewById(R.id.imageView);
BitmapDrawable  drawable = (BitmapDrawable)img.getDrawable();
bmp = drawable.getBitmap();

从上面的代码中也可以看到我们可以通过 Drawable 的getBitmap()方法从 Drawable 对象中提取出 Bitamp。
Android 还提供了一个 BitampFractory 工厂对象,专门让我们去获取 Bitmap 实例,主要有以下几种常用方法:

// 从资源文件中解码出 Bitmap
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 使用示例

通过这两节的学习,我们知道 Drawable 和 Bitmap 可以相互转换,接下来编写一个示例完成将 ImageView 中的 Drawable 对象保存到本地的示例程序。

4.1 MainActivity 截图功能

package com.emercy.myapplication;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends Activity {
    static ByteArrayOutputStream byteOut = null;
    private Bitmap bitmap = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_cut = (Button) findViewById(R.id.button);
        btn_cut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                capture();
            }
        });
    }

    public void capture() {
        Runnable action = new Runnable() {
            @Override
            public void run() {
                final View contentView = getWindow().getDecorView();
                try {
                    bitmap = Bitmap.createBitmap(contentView.getWidth(),
                            contentView.getHeight(), Bitmap.Config.ALPHA_8);
                    contentView.draw(new Canvas(bitmap));
                    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteOut);
                    save(bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (null != byteOut)
                            byteOut.close();
                        if (null != bitmap && !bitmap.isRecycled()) {
                            bitmap = null;
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        };
        try {
            action.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void save(Bitmap b) {
        FileOutputStream fos;
        try {
            fos = new FileOutputStream("sdcard/short.png");
            boolean success = b.compress(Bitmap.CompressFormat.PNG, 80, fos);
            fos.flush();
            fos.close();
            if (success) {
                Toast.makeText(MainActivity.this, "截图完成", Toast.LENGTH_SHORT).show();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

capture()方法中,我们获取当前 Activity 的“DecorView”(Activtiy 的顶层 View,我们设置的 CotentView 是其子 View),然后获取 DecorView 的输入流并会转化成 Bitmap,最后直接输出到文件中即可。

4.2 布局文件

这一节的布局文件可以任意,你可以尝试写出各种复杂的 UI 样式,因为上面的capture()方法是从“DecorView”中获取 Bitmap,所以无论你写了多少 View,最终都会通过setContentView()设置到“ContentView”中,而 ContentView 也是在 DecorView 中的,所以无论怎么写都逃离不开截图范围,最后记得加一个 Button 用于触发截屏。

5. 小结

本节进一步讲述了 Andorid 图像相关的内容,相比 Drawable,Bitmap 直接对应一张图片,更加具体。它可以与 Drawable 相互转化,并提供了多种 API 来直接操作一张图片,在做图片裁剪和修改的场景非常适用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/600043.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用IIS部署Vue项目

前提 使用IIS部署Vue项目,后端必须跨域,不要在Vue中用proxy跨域,那个只在dev环境中有用! IIS安装,不用全部打勾,有些他默认就是方块 ■ 选择性安装的,就维持原样就可以。 添加网站配置 右键…

nginx模型设计和进程讲解

一. Nginx进程模型解析 1. master主进程 和 worker工作进程 [rootlocalhost sbin]# ps -ef|grep nginx root 15411 1 0 21:08 ? 00:00:00 nginx: master process ./nginx nobody 15412 15411 0 21:08 ? 00:00:00 nginx: worker process root…

通过颜色学习css

文章目录 1.生成html2.添加css链接3.将h1标签text-align元素4.添加div标签4.1、为类marker添加元素4.2、添加两个新的div标签4.3、修改div标签的类型并修改css元素4.4、为类container添加元素4.5、以数字形式添加颜色4.5、container添加padding属性4.6、组合css中的颜色属性4.7…

python abs函数怎么用

abs()函数是Python的数字函数,用以返回数字的绝对值。 语法 以下是 abs() 方法的语法: abs( x ) 参数 x -- 数值表达式,可以是整数,浮点数,复数。 返回值 函数返回 x(数字)的绝对值&#x…

【自然语言处理】seq2seq模型——机器翻译

seq2seq模型——机器翻译 1 任务目标 1.1 案例简介 seq2seq是神经机器翻译的主流框架,如今的商用机器翻译系统大多都基于其构建,在本案例中,我们将使用由NIST提供的中英文本数据训练一个简单的中英翻译系统,在实践中学习seq2se…

uniapp文本框上下滚动问题

一个基本需求,textarea标签没有办法通过手拖动的方式进行滚动,当文字超出其容量后,想要编辑上面被遮挡部分的文字这边难以点到,电脑可以鼠标滚轮,但手机需要拖动但无效: 下面提供了我的解决思路&#xff1a…

list的模拟实现

目录 1.默认成员函数模拟实现 1.1 构造函数(头节点) 1.2 析构函数 1.3 拷贝构造函数 1.4 赋值重载函数 2.增删查改模拟实现 2.1 insert 2.2 erase 2.3 push_back、pop 3.前置、--、后置、-- 3.1前置: 3.2后置: 3.3 …

STC89C52驱动XPT2046AD转换

目录 简介封装接线(单端)时序以及命令字SPI时序命令字 程序XPT2046.CXPT2046.hmain.c测试 简介 XPT2046是一款4线电阻式触摸屏控制器,采用12位125 kHz采样SAR类型A / D转换器。XPT2046工作电压低至2.2V,支持1.5V至VCC的数字I/O接…

休斯《公共管理导论》第5版/考研真题解析/章节题库

第一部分 考研真题精选 一、概念题二、简答题三、论述题四、案例分析题第二部分 章节题库 第1章 一个变革的时代第2章 政府的角色第3章 传统的公共行政模式第4章 公共管理第5章 公共政策第6章 治 理第7章 问 责第8章 利害关系人和外部环境第9章 管制、外包和公共企…

jenkins目录下的vue3项目——pnpm install后运行报错——奇葩问题解决

昨天到今天,同事那边遇到一个问题,就是关于vue3vite的项目,在执行了自动打包后,运行代码会提示报错的问题。 报错信息如下: 具体错误信息如下: ERROR 11:28:14 [vite] Pre-transform error: Cannot find …

Xshell连接提示“SSH服务器拒绝了密码”

原因1:数字锁没有打开 没有打开NumLock(数字小键盘上面有一个【Num】按键),需要按键开启。 注意要检查NumLock灯是否亮起。 或者改成用字母键上面的数字键输入就好了。 原因2:root密码设置错误(这个是比较常…

frp内网穿透服务搭建与使用

frp内网穿透服务搭建与使用 1、frp简介 frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。 可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。frp工作原理 服务端运行,监听一个主端口…

深入Django:用户认证与权限控制实战指南

title: 深入Django:用户认证与权限控制实战指南 date: 2024/5/7 18:50:33 updated: 2024/5/7 18:50:33 categories: 后端开发 tags: AuthDecoratorsPermissionsGuardianRESTAuthSessionMgmtMFA 第1章:入门Django与设置 1.1 Django安装与环境配置 在…

netty 高性能架构设计--零拷贝

文章目录 前言一、直接内存1.1 什么是直接内存1.2 代码实现1.3 使用直接内存的优缺点 二、netty 零拷贝设计2.1 netty 直接内存2.2 netty 内存池 三、零拷贝的两种方式 前言 本篇从源码层面剖析 netty 高性能架构设计之零拷贝,并且扩展讲述零拷贝的两种实现方式。 …

并发编程之阻塞队列BlockingQueue实战及其原理分析

1. 阻塞队列介绍 1.1 队列 是限定在一端进行插入,另一端进行删除的特殊线性表。 先进先出(FIFO)线性表。 允许出队的一端称为队头,允许入队的一端称为队尾。

机器学习第二天(监督学习,无监督学习,强化学习,混合学习)

1.是什么 基于数据寻找规律从而建立关系,进行升级,如果是以前的固定算式那就是符号学习了 2.基本框架 3.监督学习和无监督式学习: 监督学习:根据正确结果进行数据的训练; 在监督式学习中,训练数据包括输…

简易录制视频做3D高斯

系统环境 ubuntu20 ,cuda11.8,anaconda配置好了3D高斯的环境。 具体参考3D高斯环境配置:https://blog.csdn.net/Son_of_the_Bronx/article/details/138527329?spm1001.2014.3001.5501 colmap安装:https://blog.csdn.net/Son_of…

W801学习笔记二十一:英语背单词学习应用——上

英语背单词是比较常见的学习APP,参考唐诗宋词应用,本章做一个类似的应用。 一、单词数据清洗及格式转换 诗词数据的获取渠道很多,一般可以按照年级来分文件。如一到九年级,四六级,雅思等等。 1、先从网上某某地方下载…

硬件设计细节1-缓冲驱动器使用注意事项

目录 一、缓冲驱动器二、实例分析1.硬件结构2.问题描述3.原因分析4.原因定位 三、结论 一、缓冲驱动器 缓冲驱动器通常用于隔离、电平转换等应用场景。在使用时,需要关注的点较多,如电平范围、频率范围、延时、控制方式、方向以及输入输出状态。通常&am…

JavaScript异步编程——03-Ajax传输json和XML

Ajax 传输 JSON JSON 的语法 JSON(JavaScript Object Notation):是 ECMAScript 的子集。作用是进行数据的交换。语法更为简洁,网络传输、机器解析都更为迅速。 语法规则: 数据在键值对中 数据由逗号分隔 花括号保存对象 方括号保存数组…