Android进阶之路 - 双端交互之传递Base64图片
今年换完工作后一直比较卷,虽然草稿箱存了几篇,但是还是先选了这篇发出来
该篇由来:主要是在使用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图片相关推荐
- Android进阶之路 - 解决部分手机拍照之后图片被旋转的问题
这几天犯了一个错误,初期想着甩锅给后台的- 但还好及时发现了是自身的问题~ 关联文章 Android基础进阶 - 调用拍照.获取图片(基础) Android基础进阶 - 获取.调用相册内图片(基础) ...
- Android进阶之路 - 批量下载、缓存图片、视频
之前已经记录过,批量下载图片和缓存本地的方式,此篇主要记录批量下载图片.视频,同时缓存在本地的功能实现 关联篇 Android进阶之路 - 批量下载.缓存图片 Android进阶之路 - 批量下载.缓 ...
- Android进阶之路 - 软键盘中右下角的设置与监听
在项目中,多多少少会遇到修改软键盘右下角按钮的需求,虽然已经写过几次,但是还是觉得在这里专心做个笔记比较放心 ~ 我的那些软键盘Blog ~ Android进阶之路 - 常见软键盘操作行为 Andro ...
- ZYNQ进阶之路14--PS端uart串口接收不定长数据
ZYNQ进阶之路14--PS端uart串口接收不定长数据 导语 ZYNQ串口简介 实现步骤 导语 繁忙的博主又来了,本节我们实现一个比较简单的东西:串口.之前的章节中我们也有使用PS端的串口进行收发数 ...
- Android进阶之路 - 批量下载、缓存图片
在日常项目开发中,关于图片批量下载,数据缓存的相关功能比比皆是,这次也是去年在项目中需要在本地缓存商品数据,所以用到了批量下载的功能,特此记录 ~ 关联篇 Android进阶之路 - 批量下载.缓存图 ...
- Android进阶之路 - 存、取、读 本地 Json 文件
最近在开发中又开始加载一些本地的json数据源,回头看之前竟然没记录,赶紧记录一波 ~ 如何准备一个合格的json文件? AndoridStudio中如何存放json文件? 如何读取本地Json文件数 ...
- 浅谈Android进阶之路
原址 过去十年是移动互联网蓬勃发展的黄金期,相信每个人也都享受到了移动互联网红利,在此期间,移动互联网经历了曙光期.成长期.成熟期.现在来说已经进入饱和期.依然记得在 2010-2013 年期间,从事 ...
- Android 进阶之路(我的博客文章目录)
原文地址:http://blog.csdn.net/u011240877 为了方便读者阅读以及自己回顾,总结写过的文章和一些想要写的文章目录如下: #1.Java Java 解惑:Comparable ...
- Android 进阶之路:ASM 修改字节码,这样学就对了!
本文已授权个人公众号「鸿洋」原创发布. 恢复双休了,准备捡起来写博客这件事,会尝试写好每一篇博客,准备写一个「进阶之路」的系列,希望对你有用. 没错,看了很多 ASM 入门的文章,都感觉文章写的很轻松 ...
- Android进阶之路 - WebView的使用与后退键处理
本篇为大家带来的是WebView的多种使用场景讲解,说起WebView往往给大家带来的印象应该是Android与H5的混合开发,下面洒家为大家进行详细讲解 我那些关于WebView的回忆 ~ 包含入门 ...
最新文章
- ADODB.Connection 错误 '800a0e7a'
- 基于centos6的mysql5.7.13主从部署(一)
- javase开发工具包中的什么命令负责运行应用程序_JavaSE之编程概述
- mysql 在字段中计算_整数在MySQL的计算字段中
- 解决VS命令提示符 “Setting environment for using Microsoft Visual Studio. 此时不应有“系列错误
- HDR高动态压缩【MATLAB代码】
- 贴片电容的0.65T,0.8T,1.25T,2.5T是什么意思
- axure 7.0 7.0.0.3142 简体中文版(附汉化包注册)
- python与vb语言_vb.net和python区别是什么
- 【IMX6ULL笔记】--内核底层驱动初步探究
- 街头篮球手游服务器维护,街头篮球手游2017.6.22维护更新公告 宝箱位置调整更新一览...
- 【娱乐】Android实现监听通话、发送短信
- vant 动态 粘性布局_Sticky 粘性布局
- PE结构-空白区手动添加任意代码(附实例代码)
- 基于matlab的运动目标检测,基于matlab的运动目标检测.doc
- linux 设置自动退出时间,linux配置超时不操作自动退出登录TMOUT
- Serverless开源框架对比
- 浏览ASP时遇到以下错误: Microsoft VBScript 运行时错误 错误 '800A01AD' ActiveX 部件不能创建对象:'NetBox.HttpServer'
- [创业之路-51] :动态股权机制 -6- 创始团队股权比例如何分配比较合理
- PDF格式分析(二十三)Action动作