介绍
图片在网络上,通常以二进制文件传输,但是可不可以用纯文本传输图片呢?答案是肯定的。
本文就简要介绍一下 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!