今年换完工作后一直比较卷,虽然草稿箱存了几篇,但是还是先选了这篇发出来

该篇由来:主要是在使用mPass H5容器与前端交互时,需要上传图片给前端,所以最终采用了图片转base64编码的方式完成了任务

  • 基础认知
  • 实现方式
    • Bitmap转Base64
    • Base64转Bitmap
    • File转Base64
    • Base64转为图片文件
  • 转换工具
    • 菜鸟工具-在线图片转Base64编码
    • 图片转base64
    • BASE64转图片
  • 所遇问题
    • bad base–64

基础认知

常规在移动端上传图片,主要有以下俩种方式

  • 将图片上传到图片服务器,服务器返回图片url,然后将图片url传递到后端、前端
  • 将图片以流的方式传到后端、或、前端,也就是将图片转为base64编码(此篇所讲)

Android在util包中提供了android.util.Base64类,该类提供了四个编码方法,分别是

public static byte[] encode(byte[] input, int flags)
public static byte[] encode(byte[] input, int offset, int len, int flags)
public static String encodeToString(byte[] input, int flags)
public static String encodeToString(byte[] input, int offset, int len, int flags)

提供了三个解码

public static byte[] decode(String str, int flags)
public static byte[] decode(byte[] input, int flags)
public static byte[] decode(byte[] input, int offset, int len, int flags)

我们发现,四个编码方法都有一个flags参数,这就是编码标志位,或者编码标准。

编码标准有以下几种:

编码 含义
CRLF Win风格的换行符,意思就是使用CR和LF这一对作为一行的结尾而不是Unix风格的LF。
CRLF 是Carriage-Return Line-Feed的缩写,意思是回车(\r)换行(\n)。也就是说,Window风格的行结束标识符是\r\n,Unix风格的行结束标识符是\n。
DEFAULT 这个参数是默认,使用默认的方法来加密
NO_PADDING 这个参数是略去加密字符串最后的"="
NO_WRAP 这个参数意思是略去所有的换行符(设置后CRLF就没用了)
URL_SAFE 这个参数意思是加密时不使用对URL和文件名有特殊意义的字符来作为加密字符,具体就是以-和_取代+和/。
NO_CLOSE 通常与Base64OutputStream一起使用,是传递给Base64OutputStream的标志指示它不应关闭正在包装的输出流。

实现方式

Bitmap转Base64

场景:移动端拍照或相册选取图片后,转为base64字符串传给H5前端

亲测可用

    /*** bitmap转为base64** @param bitmap* @return*/public static String bitmapToBase64(Bitmap bitmap) {String result = null;ByteArrayOutputStream baos = null;try {if (bitmap != null) {baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);baos.flush();baos.close();byte[] bitmapBytes = baos.toByteArray();result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);}} catch (IOException e) {e.printStackTrace();} finally {try {if (baos != null) {baos.flush();baos.close();}} catch (IOException e) {e.printStackTrace();}}return result;}
Base64转Bitmap

场景:获取前端传递的base64图片串,存储于本地相册

亲测可用

    /*** base64转为bitmap** @param base64Data* @return*/public static Bitmap base64ToBitmap(String base64Data) {byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);}
File转Base64

场景:拍照后将File转为Base64传给前端
亲测可用

    /*** 将图片转换成Base64编码的字符串*/public static String fileToBase64(String path) {if (TextUtils.isEmpty(path)) {return null;}InputStream is = null;byte[] data = null;String result = null;try {is = new FileInputStream(path);//创建一个字符流大小的数组。data = new byte[is.available()];//写入数组is.read(data);//用默认的编码格式进行编码result = Base64.encodeToString(data, Base64.NO_CLOSE);} catch (Exception e) {e.printStackTrace();} finally {if (null != is) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}return result;}

注意:未亲测

代码
/*
url, 本地路径
ext, 图片后缀
width, 图片宽度
height, 图片高度
callback 回调函数 用来取值
*/getUrlBase64(url, ext, width, height, callback) {var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d");var img = new Image();img.crossOrigin = "Anonymous"; img.src = url;img.onload = function () {canvas.height = height; canvas.width = width; ctx.drawImage(img, 0, 0, width, height); var dataURL = canvas.toDataURL("image/" + ext);callback.call(this, dataURL); canvas = null;};},getUrl(val) {// val:图片的base64路径},调用this.getUrlBase64(require("@/assets/img/bg-01.png"),"png",470,348,this.getUrl);

未亲测 - 应用场景:图片上传至服务器至指定目录,前端请求返回base64字符串直接显示浏览图片

/*** 图片转化成base64字符串,返回的string可以直接在src上显示* @param file   图片文件* @param fileType  图片格式* @return* @throws IOException*/
public static String getImageStr(File file, String fileType) throws IOException {String fileContentBase64 = null;String base64Str = "data:" + fileType + ";base64,";String content = null;//将图片文件转化为字节数组字符串,并对其进行Base64编码处理InputStream in = null;byte[] data = null;//读取图片字节数组try {in = new FileInputStream(file);data = new byte[in.available()];in.read(data);in.close();//对字节数组Base64编码if (data == null || data.length == 0) {return null;}content = Base64.encodeBytes(data);if (content == null || "".equals(content)) {return null;}fileContentBase64 = base64Str + content;} catch (IOException e) {e.printStackTrace();} finally {if (in != null) {in.close();}}return fileContentBase64;
}
Base64转为图片文件

注意:未亲测

    /*** 将Base64编码转换为图片** @param base64Str* @param path* @return true*/public static boolean base64ToFile(String base64Str, String path) {byte[] data = Base64.decode(base64Str, Base64.NO_WRAP);for (int i = 0; i < data.length; i++) {if (data[i] < 0) {//调整异常数据data[i] += 256;}}OutputStream os = null;try {os = new FileOutputStream(path);os.write(data);os.flush();os.close();return true;} catch (FileNotFoundException e) {e.printStackTrace();return false;} catch (IOException e) {e.printStackTrace();return false;}}

注意:未亲测

public final class Base64Util {private static final String TAG = "Base64Utils";public Base64Util() {}public static byte[] decode(String var0) {byte[] var1 = new byte[0];try {return var0 != null ? Base64.decode(var0, 0) : var1;} catch (IllegalArgumentException var3) {Log.e(TAG, "decode failed : " + var3.getMessage());return var1;}}public static byte[] decodeUrlSafe(String var0) {byte[] var1 = new byte[0];try {return var0 != null ? Base64.decode(var0, 10) : var1;} catch (IllegalArgumentException var3) {Log.e(TAG, "decodeUrlSafe failed : " + var3.getMessage());return var1;}}public static byte[] decodeUrlSafeNoPadding(String var0) {byte[] var1 = new byte[0];try {return var0 != null ? Base64.decode(var0, 11) : var1;} catch (IllegalArgumentException var3) {Log.e(TAG, "decodeUrlSafeNoPadding failed : " + var3.getMessage());return var1;}}public static String encode(byte[] var0) {return var0 != null ? Base64.encodeToString(var0, 0) : null;}public static String encodeUrlSafe(byte[] var0) {return var0 != null ? Base64.encodeToString(var0, 10) : null;}public static String encodeUrlSafeNoPadding(byte[] var0) {return var0 != null ? Base64.encodeToString(var0, 11) : null;}/*** base64转化成图片文件** @param base64* @param imgFilePath* @return*/public static boolean generateImage(String base64, String imgFilePath) {// 对字节数组字符串进行Base64解码并生成图片if (base64 == null) // 图像数据为空return false;try {// Base64解码byte[] bytes = Base64Util.decode(base64);for (int i = 0; i < bytes.length; ++i) {if (bytes[i] < 0) {// 调整异常数据bytes[i] += 256;}}// 生成jpeg图片OutputStream out = new FileOutputStream(imgFilePath);out.write(bytes);out.flush();out.close();return true;} catch (Exception e) {Log.e(TAG, e.getMessage());return false;}}}

转换工具

很多时候我们需要判断图片转换base64或base64转图是否正常、正确,那么就可以借用以下工具了

菜鸟工具-在线图片转Base64编码

图片转base64

BASE64转图片

所遇问题

bad base–64

大致异常:java.lang.IllegalargumentException:bad base–64

其实主要原因就是你的base64编码有问题,可以看看格式,如下红框内的数据就是多余的,需要及时删除

解决方法 - 具体如下

Android进阶之路 - 双端交互之传递Base64图片相关推荐

  1. Android进阶之路 - 解决部分手机拍照之后图片被旋转的问题

    这几天犯了一个错误,初期想着甩锅给后台的- 但还好及时发现了是自身的问题~ 关联文章 Android基础进阶 - 调用拍照.获取图片(基础) Android基础进阶 - 获取.调用相册内图片(基础) ...

  2. Android进阶之路 - 批量下载、缓存图片、视频

    之前已经记录过,批量下载图片和缓存本地的方式,此篇主要记录批量下载图片.视频,同时缓存在本地的功能实现 关联篇 Android进阶之路 - 批量下载.缓存图片 Android进阶之路 - 批量下载.缓 ...

  3. Android进阶之路 - 软键盘中右下角的设置与监听

    在项目中,多多少少会遇到修改软键盘右下角按钮的需求,虽然已经写过几次,但是还是觉得在这里专心做个笔记比较放心 ~ 我的那些软键盘Blog ~ Android进阶之路 - 常见软键盘操作行为 Andro ...

  4. ZYNQ进阶之路14--PS端uart串口接收不定长数据

    ZYNQ进阶之路14--PS端uart串口接收不定长数据 导语 ZYNQ串口简介 实现步骤 导语 繁忙的博主又来了,本节我们实现一个比较简单的东西:串口.之前的章节中我们也有使用PS端的串口进行收发数 ...

  5. Android进阶之路 - 批量下载、缓存图片

    在日常项目开发中,关于图片批量下载,数据缓存的相关功能比比皆是,这次也是去年在项目中需要在本地缓存商品数据,所以用到了批量下载的功能,特此记录 ~ 关联篇 Android进阶之路 - 批量下载.缓存图 ...

  6. Android进阶之路 - 存、取、读 本地 Json 文件

    最近在开发中又开始加载一些本地的json数据源,回头看之前竟然没记录,赶紧记录一波 ~ 如何准备一个合格的json文件? AndoridStudio中如何存放json文件? 如何读取本地Json文件数 ...

  7. 浅谈Android进阶之路

    原址 过去十年是移动互联网蓬勃发展的黄金期,相信每个人也都享受到了移动互联网红利,在此期间,移动互联网经历了曙光期.成长期.成熟期.现在来说已经进入饱和期.依然记得在 2010-2013 年期间,从事 ...

  8. Android 进阶之路(我的博客文章目录)

    原文地址:http://blog.csdn.net/u011240877 为了方便读者阅读以及自己回顾,总结写过的文章和一些想要写的文章目录如下: #1.Java Java 解惑:Comparable ...

  9. Android 进阶之路:ASM 修改字节码,这样学就对了!

    本文已授权个人公众号「鸿洋」原创发布. 恢复双休了,准备捡起来写博客这件事,会尝试写好每一篇博客,准备写一个「进阶之路」的系列,希望对你有用. 没错,看了很多 ASM 入门的文章,都感觉文章写的很轻松 ...

  10. Android进阶之路 - WebView的使用与后退键处理

    本篇为大家带来的是WebView的多种使用场景讲解,说起WebView往往给大家带来的印象应该是Android与H5的混合开发,下面洒家为大家进行详细讲解 我那些关于WebView的回忆 ~ 包含入门 ...

最新文章

  1. ADODB.Connection 错误 '800a0e7a'
  2. 基于centos6的mysql5.7.13主从部署(一)
  3. javase开发工具包中的什么命令负责运行应用程序_JavaSE之编程概述
  4. mysql 在字段中计算_整数在MySQL的计算字段中
  5. 解决VS命令提示符 “Setting environment for using Microsoft Visual Studio. 此时不应有“系列错误
  6. HDR高动态压缩【MATLAB代码】
  7. 贴片电容的0.65T,0.8T,1.25T,2.5T是什么意思
  8. axure 7.0 7.0.0.3142 简体中文版(附汉化包注册)
  9. python与vb语言_vb.net和python区别是什么
  10. 【IMX6ULL笔记】--内核底层驱动初步探究
  11. 街头篮球手游服务器维护,街头篮球手游2017.6.22维护更新公告 宝箱位置调整更新一览...
  12. 【娱乐】Android实现监听通话、发送短信
  13. vant 动态 粘性布局_Sticky 粘性布局
  14. PE结构-空白区手动添加任意代码(附实例代码)
  15. 基于matlab的运动目标检测,基于matlab的运动目标检测.doc
  16. linux 设置自动退出时间,linux配置超时不操作自动退出登录TMOUT
  17. Serverless开源框架对比
  18. 浏览ASP时遇到以下错误: Microsoft VBScript 运行时错误 错误 '800A01AD' ActiveX 部件不能创建对象:'NetBox.HttpServer'
  19. [创业之路-51] :动态股权机制 -6- 创始团队股权比例如何分配比较合理
  20. PDF格式分析(二十三)Action动作

热门文章

  1. 图像缩放之双线性插值
  2. access 分表存储_数据库分区、分表、分库、分片
  3. C++的multi_map如何输出所有key值相等的元素
  4. CentOS 6.7安装gcc4.8.2
  5. java编程常用软件
  6. 圈圈教你玩usb第一版硬件实物使用说明
  7. php实现我的购物以及订单,实现简单的php购物车代码
  8. c语言入门程序下载,c语言入门自学软件下载
  9. 计算机新建没有文本文档,我的电脑新建文本文档没有显示TXT,为什么?
  10. 自由职业者互联网进化记