3分钟教你图解Bitmap编码传输
在Android的图片传输的流程为:
Bitmap的转换为二进制流:
//将bitmap转换为二进制流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
其中,我们知道compress的方法是进行压缩的,其中方法里面的三个参数,分别代表:图片格式、压缩比例、字节流(节数组输出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中)。
其实这个时候我想到了一个问题,当压缩比例为100的时候,也就是没有进行压缩,那这一步的代码意义何在呢? 经过研究下面源码:
/*** Write a compressed version of the bitmap to the specified outputstream.* If this returns true, the bitmap can be reconstructed by passing a* corresponding inputstream to BitmapFactory.decodeStream(). Note: not* all Formats support all bitmap configs directly, so it is possible that* the returned bitmap from BitmapFactory could be in a different bitdepth,* and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque* pixels).** @param format The format of the compressed image* @param quality Hint to the compressor, 0-100. 0 meaning compress for* small size, 100 meaning compress for max quality. Some* formats, like PNG which is lossless, will ignore the* quality setting* @param stream The outputstream to write the compressed data.* @return true if successfully compressed to the specified stream.*/public boolean compress(CompressFormat format, int quality, OutputStream stream) {checkRecycled("Can't compress a recycled bitmap");// do explicit check before calling the native methodif (stream == null) {throw new NullPointerException();}if (quality < 0 || quality > 100) {throw new IllegalArgumentException("quality must be 0..100");}StrictMode.noteSlowCall("Compression of a bitmap is slow");Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");boolean result = nativeCompress(mNativePtr, format.nativeInt,quality, stream, new byte[WORKING_COMPRESS_STORAGE]);Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);return result;}
其中最重要的一句代码是这个:
nativeCompress(mNativePtr, format.nativeInt,quality, stream, new byte[WORKING_COMPRESS_STORAGE]);
再深入发现调用的是这个方法:
private static native boolean nativeCompress(long nativeBitmap, int format,int quality, OutputStream stream,byte[] tempStorage);
我们最后发现它最后是调用到了JNI,直接使用.cpp方法里面的C++函数了。这个大家有兴趣可以去参考这篇文章:Bitmap压缩原理解析与Android 7.0之前通过NDK使用libjpeg库高质量压缩图片。
所以回到我们的第一个源码那,看注释,第一句是 Write a compressed version of the bitmap to the specified outputstream. 意思就是将压缩后的Bitmap写入到指定的输出流里面。这样我就弄懂了,其实这个压缩如果是100的话,其最终的目的也就是去将bitmap写入到流里面。流(Stream)二进制数据流,内存中电信号转换,写入到磁盘的存储颗粒上,记录电信号。
二进制流转换为Byte[]数组
- 这个就涉及到了编码的知识了。在最早期的时候,大家的编码方式都使用的是ASCII码的编码方式,而我们要知道的是在计算机中,所有的信息都是以0和1来进行存储的,指定的二进制代表了字母、标点符号、控制字符。譬如存储在计算机上的01000001代表了大写字母A。ASCII码一共有256个,但是常用的也就前128个,标准ASCII码(0~127)。
- 简而言之,对于字符而言,直接用ASCII码对应的数字表示,ASCII码就是用来将字符存储到计算机的,例如“3” 的ASCII码的十进制为51 ,二进制为 0011 0011 。则是将二进制的值存储到了计算机。
- 那么,由此延伸的一个问题是:当本身就是十进制的51,其二进制也为0011 0011 ,存储进了计算机。那么在计算机中的二进制 0011 0011,表现到内存中到底是字符还是数字呢? 我自我理解是计算机中既然存储了0011 0011 那么在内存中表示出来的值,只与其定义的数有关,如果你定义的是int 那么就是51;如果你定义的是String 那么就是“3”。
- 而Byte里面存储为8bit,可以存储所有ASCII所有字符(这是它包含8bits的初衷)。也就是说1Byte里面有8bit的二进制,那么将二进制流每8bit存储于一个Byte,就可以得到最后转换的Byte[]数组了。
Byte[]数组转Base64编码
什么是Base64编码
漫画:什么是Base64算法?
为什么要进行Base64编码
因为Http协议(超文本传输协议)中,Byte里面的二进制可能为0000 0001B,如果直接转换为String的话,明显是不可能的,因为这个不是可打印字符,那么传输过程中可能就会出现乱码,而Base64也就是64个可打印的字符串。
Value | Char | Value | Char | Value | Char | Value | Char |
---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w |
1 | B | 17 | R | 33 | h | 49 | x |
2 | C | 18 | S | 34 | i | 50 | y |
3 | D | 19 | T | 35 | j | 51 | z |
4 | E | 20 | U | 36 | k | 52 | 0 |
5 | F | 21 | V | 37 | l | 53 | 1 |
6 | G | 22 | W | 38 | m | 54 | 2 |
7 | H | 23 | X | 39 | n | 55 | 3 |
8 | I | 24 | Y | 40 | o | 56 | 4 |
9 | J | 25 | Z | 41 | p | 57 | 5 |
10 | K | 26 | a | 42 | q | 58 | 6 |
11 | L | 27 | b | 43 | r | 59 | 7 |
12 | M | 28 | c | 44 | s | 60 | 8 |
13 | N | 29 | d | 45 | t | 61 | 9 |
14 | O | 30 | e | 46 | u | 62 | + |
15 | P | 31 | f | 47 | v | 63 | / |
3分钟教你图解Bitmap编码传输相关推荐
- 美女工程师教你一分钟学会信号发生器复杂信号编码输出
美女工程师教你一分钟学会信号发生器复杂信号编码输出
- 三分钟教你快速选择机器视觉传感器
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|新机器视觉 六招教您合理选择机器视觉传感器 传感器是一种 ...
- 所见即搜,3分钟教你搭建一个服装搜索系统!
摘要:用MindSpore+Jina,基于Fashion-MNIST Dataset搭建的服装搜索系统. 引言 各位算法萌新们,是不是经常训练了模型却不知道如何部署和应用?或者只会调参但不会前端后端所 ...
- 10分钟教你用python如何正确把妹
前言 今天没妹子约,刚好研究一下.如何用神奇的python打造一个把妹神器吧.看完这个,你们就能走向人生巅峰,迎娶白富美啦. 我知道你们想看看效果 当然啦,这只是测试版的效果,真正的版本可比这个厉害多 ...
- matlab计算正负零序分量,5分钟教你正确理解电力系统中的正序负序零序.doc
5分钟教你正确理解电力系统中的正序负序零序 电力 三相不平衡 作图法 对称分量法 1:三相不平衡的的电压(或电流),可以分解为平衡的正序.负序和零序 2:零序为3相电压向量相加,除以3 3:正序将BC ...
- 十分钟教你掌握CPU缓存
十分钟教你掌握CPU缓存 一. 基础知识 二. 缓存命中 三.缓存一致 四.程序性能 示例一 示例二 示例三 一. 基础知识 首先,大家都知道现在CPU的多核技术,都会有几级缓存,现在的CPU会 ...
- 研究生二年级该怎么安排_教二年级学生编码是什么感觉
研究生二年级该怎么安排 在大流行中进行教学–一半的老师,一半的技术支持 (Teaching in the Middle of a Pandemic - Half Teacher, Half Tech ...
- vue前端用服务器上路径的图片展示_5分钟教你用nodeJS手写一个mock数据服务器
对于前端开发者而言,javascript正扮演着越来越重要的地位,它不仅能为浏览器端赋能,在web服务器方面也有很大的价值(我们可以用nodeJS来写服务端代码,启动web服务器),因此本文所要描述的 ...
- 十分钟教你开发EOS智能合约
十分钟教你开发EOS智能合约 在CSDN.柏链道捷(PDJ Education).HelloEOS.中关村区块链产业联盟主办的「EOS入门及最新技术解读」专场沙龙上,柏链道捷(PDJ Educatio ...
最新文章
- 合并果子(NOIP2004)
- blur失焦方法会触发两次_中央空调维修过程中,晶闸管和电容器的检测方法
- Cordova打包的Vue项目在IOS无法拉起支付宝和微信支付
- python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁
- 谈晶体管的饱和状态和饱和压降
- Php xml 目录,PHP-PHP+xml的无限分类树目录的方法?
- 基于JAVA+Servlet+JSP+MYSQL的设备管理系统
- python3socket非阻塞_Python的socket.accept非阻塞吗?
- Customer Exit
- 安装torchsnooper、convokit、entmax库
- 加密--HashPasswordForStoringInConfigFile过时问题
- Spring jar包下载
- pytorch实践(改造属于自己的resnet网络结构并训练二分类网络)
- 隐私计算技术|深度解读可信隐私计算框架“隐语”
- CSP/CCF计算机职业资格认证题目:[201903-1	小中大]【已解决】
- C代码如何跑起来(程序编译和预处理)
- 记录一个解决mysql5.7.32-Access denied for user ‘‘@‘localhost‘ (using password NO)skip-grant-tables不生效的问题
- Linux(CentOS)安装MySQL教程
- 使用Redux-Toolkit,由“object is not extensible”引发的思考及解决方案
- 车载诊断测试——无诊断数据库怎么使用CANoe做诊断测试?
热门文章
- java 获取浏览器名称及版本号
- EDM实例之15个节日邮件标题分享
- 2022-2028全球手持式伤口成像设备行业调研及趋势分析报告
- Unity3D_(游戏)双人3D坦克_简易版
- 大一转专业计算机考什么,武汉大学 计算机 转专业 经验贴
- 面试-----211小本的求职之路拿到腾讯阿里人人网易游戏offer
- wxml 点击图片下载_跟着做,零基础也能做出自己的小程序
- android加载本地图库,Android读取本地图库与调用摄像头拍摄
- 倍速增长!裁员潮下小i机器人逆势扩招
- 使用conda管理python包和环境