python

用 base64 进行图片和字符串互转,并保存至 json - 知乎

文章暂存

systemime
2021-04-08
10 min

摘要.

用 base64 进行图片和字符串互转,并保存至 json - 知乎

首发于Python 学习之路

写文章

# 用 base64 进行图片和字符串互转,并保存至 json

Diemcoin.Network

​关注他

21 人赞同了该文章

# 介绍

图片在网络上,通常以二进制文件传输,但是可不可以用纯文本传输图片呢?答案是肯定的。

本文就简要介绍一下 Python 的 base64 库。它可以将图片转换成字符串,也可以从字符串 “变出” 一个图片来。

# 图片转成字符串,并保存至 json

首先我们假设有这么一个图片 tower.jpg,我们想把它保存成文本形式,放到一个 json 文件里,然后发送到一个服务器程序。

# 导入相关的库
from sys import argv
from base64 import b64encode
from json import dumps
ENCODING = 'utf-8'    # 指定编码形式
SCRIPT_NAME, IMAGE_NAME, JSON_NAME = argv    # 获得文件名参数
# 读取二进制图片,获得原始字节码,注意 'rb'
with open(IMAGE_NAME, 'rb') as jpg_file:
    byte_content = jpg_file.read()
# 把原始字节码编码成 base64 字节码
base64_bytes = b64encode(byte_content)
# 将 base64 字节码解码成 utf-8 格式的字符串
base64_string = base64_bytes.decode(ENCODING)
# 用字典的形式保存数据
raw_data = {}
raw_data["name"] = IMAGE_NAME
raw_data["image_base64_string"] = base64_string
# 将字典变成 json 格式,缩进为 2 个空格
json_data = dumps(raw_data, indent=2)
# 将 json 格式的数据保存到文件中
with open(JSON_NAME, 'w') as json_file:
    json_file.write(json_data)

代码写好之后,将之保存为 image_to_json.py

使用方法

python3 image_to_json.py tower.jpg tower.json

不出意外的话,会在当前目录得到一个名为 tower.json 的文件,打开后可以看到类似的数据:

{
  "name": "tower.jpg",
  "image_base64_string": "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/.................."
}

"image_base64_string" 字段后面的字符串非常长,全部在一行内,有几十万甚至几千万个看不懂的字母。如果你的图片很大,比如 40M,那么这一行字符串很可能会让你的编辑器爆掉。

如果你需要将这个文件发送至一个服务器程序,可以使用类似的命令:

curl -vX POST http://xxx.xxx.xxx.xxx:80/api -d @tower.json --header "Content-Type: application/json"

这样发送一个 POST 请求后,设计好的后端服务器程序将可以直接读取 json 中的数据。

# 从 json 读取字符串,并转换成图片

获得 json 字符串之后,又可以将它原封不动地转成二进制文件。

from sys import argv
import base64
import json
# 从命令行获得文件名参数
SCRIPT_NAME, JSON_NAME, IMAGE_NAME = argv
# 读取 json 文件,并直接存入字典
with open(JSON_NAME, "r") as json_file:
    raw_data = json.load(json_file)
# 从字典中取得图片的 base64 字符串,形如“YABgAAD/2wBDAAYEBQYFBAY....",
image_base64_string = raw_data["image_base64_string"]
# 将 base64 字符串解码成图片字节码
image_data = base64.b64decode(image_base64_string)
# 将字节码以二进制形式存入图片文件中,注意 'wb'
with open(IMAGE_NAME, 'wb') as jpg_file:
    jpg_file.write(image_data)

代码写好后,保存为 json_to_image.py

使用方法

python3 json_to_image.py tower.json tower-new.jpg

这时在当前文件可以看到一个 tower-new.jpg 的图片文件,打开之后,会跟之前的图片一模一样。

Happy exploring!

编辑于 2017-06-11

[

base64

](//www.zhihu.com/topic/19861964)

[

JSON

](//www.zhihu.com/topic/19602492)

[

Python 入门

](//www.zhihu.com/topic/19661050)

​赞同 21​

​19 条评论

​分享

​喜欢​收藏​申请转载

# 文章被以下专栏收录

[

](//www.zhihu.com/column/c_1286313526521413632)

[

Python 学习之路

# ](//www.zhihu.com/column/c_1286313526521413632)

QQ 群号: 234673720 加群填写:学 Python

[

](//www.zhihu.com/column/dtnetwork)

[

鼎天网络

# ](//www.zhihu.com/column/dtnetwork)

鼎天网络专栏,专注于互联网技术,计算机软硬件交流。

# 推荐阅读

[

# Python JSON:编码(转储),解码(加载)json 数据和文件(示例)

疯狂的 py... 发表于 pytho...

](https://zhuanlan.zhihu.com/p/57642888)[

# Base64 编码详解

base64 是什么?Base64,顾名思义,就是包括小写字母 a-z、大写字母 A-Z、数字 0-9、符号"+"、"/"一共 64 个字符的字符集,(另加一个 “=”,实际是 65 个字符,至于为什么还会有…

刘志军发表于 Pytho...

](https://zhuanlan.zhihu.com/p/339477329)[

# 一份简明的 Base64 原理解析

mzlog... 发表于极乐科技

](https://zhuanlan.zhihu.com/p/111700349)[

# 常见 Serialize 技术探秘(XML、JSON、JDBC byte 编码、Protobuf)

目前业界有各种各样的网络输出传输时的序列化和反序列化方案,它们在技术上的实现的初衷和背景有较大的区别,因此在设计的架构也会有很大的区别,最终在落地后的:解析速度、对系统的影响、…

阿里云云栖... 发表于我是程序员

](https://zhuanlan.zhihu.com/p/48045115)

# 19 条评论

​切换为时间排序

写下你的评论...

发布

  • 湫一2018-10-30

    感谢!过程很清晰,有帮助!

    ​1​回复​踩​ 举报

  • Ryou ikonn2018-02-02

    这样做没什么用,还不如直接转二进制。因为 base64 会补码,增大了三分之一的空间。而且 gzip 压缩 率下降

    ​赞​回复​踩​ 举报

  • xxxx2017-06-18

    难道你不知道有一种东西叫做 dataurl 的东西吗?

    ​2​回复​踩​ 举报

  • Diemcoin.Network (作者) 回复xxxx2017-06-18

    感谢分享,等的就是你!

    ​1​回复​踩​ 举报

  • 「已注销」回复xxxx2017-09-13

    当你的手机 app 给 Web 服务器提交图片时,你能用 url 吗??

    这个时候:要么把图片文件放在 request 的 FIELD 字段中,要么是就像作者这样做,封装到 json 里面去。

    嘲讽是几个意思?

    ​赞​回复​踩​ 举报

查看全部 6 条回复

  • 观澜听涛2017-06-12

    抓包 ZF 单位的 H5,前端 PO 了四张图的 base64 到后端,ios 的原图,一个 post10 多 M 大。超时的情况你懂得!!!PS:python 大法好,因为 ZF 官网的不稳定,python 模拟直接 POST,谁用谁知道,啊哈哈。

    ​赞​回复​踩​ 举报

  • 安兴乐2017-06-12

    请问可不可以用 opencv 读取图片,这样就是 numpy 格式的数组了,然后直接转 json 呢? 这种方式和 base64 有什么区别吗?

    ​赞​回复​踩​ 举报

  • Diemcoin.Network (作者) 回复安兴乐2017-06-12

    你的想法很有趣,我没试过这么干,不过我想你说的应该是可行的,有人讨论过这个问题:Python OpenCV convert image to byte string?

    ​赞​回复​踩​ 举报

  • 安兴乐回复Diemcoin.Network (作者) 2017-06-12

    嗯,我这就试一试,看看可不可行。

    ​赞​回复​踩​ 举报

展开其他 3 条回复

  • Diemcoin.Network (作者) 2017-06-11

    有些时候会需要,比如你要用 json 发请求,而没有图片 url 可用的时候。

    ​赞​回复​踩​ 举报

  • 达利2017-06-11

    请问用纯文本传输的优势有哪些呢?

    ​赞​回复​踩​ 举报

1 条评论被折叠(为什么?

想来知乎工作?请发送邮件到 jobs@zhihu.com https://zhuanlan.zhihu.com/p/27134323

上次编辑于: 5/20/2021, 7:26:49 AM