55. 【Android教程】位图:Bitmap

简介: 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 来直接操作一张图片,在做图片裁剪和修改的场景非常适用。

目录
打赏
0
0
0
0
56
分享
相关文章
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
5604 2
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
593 4
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
96 20
Android经典面试题之图片Bitmap怎么做优化
Android上在两个Activity之间传递Bitmap对象
Android上在两个Activity之间传递Bitmap对象
60 2
Android Bitmap 加载与像素操作
Android Bitmap 加载与像素操作
71 2
Android中实现Bitmap在自定义View中的放大与拖动
Android中实现Bitmap在自定义View中的放大与拖动
175 1
58. 【Android教程】音频录制:MediaRecord
58. 【Android教程】音频录制:MediaRecord
88 2
|
8月前
|
杨老师课堂_安卓教程第一篇之入门
杨老师课堂_安卓教程第一篇之入门
48 0
59. 【Android教程】多线程
59. 【Android教程】多线程
83 0

热门文章

最新文章

  • 1
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    31
  • 2
    Android历史版本与APK文件结构
    14
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    81
  • 4
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    2
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    5
  • 6
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    12
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    7
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    8
  • 9
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    10
  • 10
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    8
  • 1
    android FragmentManager 删除所有Fragment 重建
    15
  • 2
    Android实战经验之Kotlin中快速实现MVI架构
    21
  • 3
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    24
  • 4
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    39
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    127
  • 6
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    40
  • 7
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    55
  • 8
    Android历史版本与APK文件结构
    149
  • 9
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    46
  • 10
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    40