本文主要记录使用Python的base64库完成图片与字符串之间的相互转换。

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

1、图片转成字符串,并保存至 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,得到的数据格式如下:

{
  "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 中的数据。

2、从 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,这时就会得到一个与原来图片一样的图片文件