在Android的图片传输的流程为:

Created with Raphaël 2.1.2Bitmap二进制流Byte数组Base64编码String进行传输Base64解码还原为原来的Byte数组,然后转换为原来的String

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编码传输相关推荐

  1. 美女工程师教你一分钟学会信号发生器复杂信号编码输出

    美女工程师教你一分钟学会信号发生器复杂信号编码输出

  2. 三分钟教你快速选择机器视觉传感器

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|新机器视觉 六招教您合理选择机器视觉传感器 传感器是一种 ...

  3. 所见即搜,3分钟教你搭建一个服装搜索系统!

    摘要:用MindSpore+Jina,基于Fashion-MNIST Dataset搭建的服装搜索系统. 引言 各位算法萌新们,是不是经常训练了模型却不知道如何部署和应用?或者只会调参但不会前端后端所 ...

  4. 10分钟教你用python如何正确把妹

    前言 今天没妹子约,刚好研究一下.如何用神奇的python打造一个把妹神器吧.看完这个,你们就能走向人生巅峰,迎娶白富美啦. 我知道你们想看看效果 当然啦,这只是测试版的效果,真正的版本可比这个厉害多 ...

  5. matlab计算正负零序分量,5分钟教你正确理解电力系统中的正序负序零序.doc

    5分钟教你正确理解电力系统中的正序负序零序 电力 三相不平衡 作图法 对称分量法 1:三相不平衡的的电压(或电流),可以分解为平衡的正序.负序和零序 2:零序为3相电压向量相加,除以3 3:正序将BC ...

  6. 十分钟教你掌握CPU缓存

    十分钟教你掌握CPU缓存 一. 基础知识 二. 缓存命中 三.缓存一致 四.程序性能 示例一 示例二 示例三 一. 基础知识    首先,大家都知道现在CPU的多核技术,都会有几级缓存,现在的CPU会 ...

  7. 研究生二年级该怎么安排_教二年级学生编码是什么感觉

    研究生二年级该怎么安排 在大流行中进行教学–一半的老师,一半的技术支持 (Teaching in the Middle of a Pandemic - Half Teacher, Half Tech ...

  8. vue前端用服务器上路径的图片展示_5分钟教你用nodeJS手写一个mock数据服务器

    对于前端开发者而言,javascript正扮演着越来越重要的地位,它不仅能为浏览器端赋能,在web服务器方面也有很大的价值(我们可以用nodeJS来写服务端代码,启动web服务器),因此本文所要描述的 ...

  9. 十分钟教你开发EOS智能合约

    十分钟教你开发EOS智能合约 在CSDN.柏链道捷(PDJ Education).HelloEOS.中关村区块链产业联盟主办的「EOS入门及最新技术解读」专场沙龙上,柏链道捷(PDJ Educatio ...

最新文章

  1. 合并果子(NOIP2004)
  2. blur失焦方法会触发两次_中央空调维修过程中,晶闸管和电容器的检测方法
  3. Cordova打包的Vue项目在IOS无法拉起支付宝和微信支付
  4. python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁
  5. 谈晶体管的饱和状态和饱和压降
  6. Php xml 目录,PHP-PHP+xml的无限分类树目录的方法?
  7. 基于JAVA+Servlet+JSP+MYSQL的设备管理系统
  8. python3socket非阻塞_Python的socket.accept非阻塞吗?
  9. Customer Exit
  10. 安装torchsnooper、convokit、entmax库
  11. 加密--HashPasswordForStoringInConfigFile过时问题
  12. Spring jar包下载
  13. pytorch实践(改造属于自己的resnet网络结构并训练二分类网络)
  14. 隐私计算技术|深度解读可信隐私计算框架“隐语”
  15. CSP/CCF计算机职业资格认证题目:[201903-1 小中大]【已解决】
  16. C代码如何跑起来(程序编译和预处理)
  17. 记录一个解决mysql5.7.32-Access denied for user ‘‘@‘localhost‘ (using password NO)skip-grant-tables不生效的问题
  18. Linux(CentOS)安装MySQL教程
  19. 使用Redux-Toolkit,由“object is not extensible”引发的思考及解决方案
  20. 车载诊断测试——无诊断数据库怎么使用CANoe做诊断测试?

热门文章

  1. java 获取浏览器名称及版本号
  2. EDM实例之15个节日邮件标题分享
  3. 2022-2028全球手持式伤口成像设备行业调研及趋势分析报告
  4. Unity3D_(游戏)双人3D坦克_简易版
  5. 大一转专业计算机考什么,武汉大学 计算机 转专业 经验贴
  6. 面试-----211小本的求职之路拿到腾讯阿里人人网易游戏offer
  7. wxml 点击图片下载_跟着做,零基础也能做出自己的小程序
  8. android加载本地图库,Android读取本地图库与调用摄像头拍摄
  9. 倍速增长!裁员潮下小i机器人逆势扩招
  10. 使用conda管理python包和环境