Encode/decode 图片到 base64 flask&python
Encode/decode image to base64 flask&python
我有一个名为 'image.png' 的图像,首先我向我的服务器请求将图像保存为 json 文件中的 base64 字符串。
def get_img_content(coding='utf-8'):
with open('image.png', 'rb') as f:
img_data = base64.b64encode(f.read()).decode(coding)
return img_data
requests.get(f'http://127.0.0.1:5000/?face={get_img_content()}')
下面我添加了处理我的请求的服务器代码
from flask import Flask, request
import os
import json
app = Flask(__name__)
if "data.json" not in os.listdir(os.getcwd()):
with open('data.json', 'a', encoding='utf-8') as f:
pass
content = {'ids': [], 'results': []}
else:
with open('data.json', 'r', encoding='utf-8') as f:
content = json.loads(f.read())
def add_id(id, face, content=content):
content['ids'].append({id: face})
with open('data.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(content))
@app.route('/', methods=['GET'])
def main():
face = request.args.get('face')
if not face:
return 'Valid request has to contain face'
id = [int(list(i.keys())[0]) for i in content['ids']]
id = str(max(id) + 1 if id else 1)
add_id(id, face)
print(content)
return id
@app.route('/get', methods=['GET'])
def get():
id = request.args.get('id')
if not id:
return 'Valid request has to contain id'
for i in content['results']:
if list(i.keys())[0] == id:
return json.dumps({'result': i[id]})
return "Couldn't find result"
if __name__ == '__main__':
app.run()
之后我尝试从 data.json 中读取这个 base64 字符串并将其转换为图像,但是我得到了 PaddingError
binascii.Error: 填充不正确
import base64
import json
with open('data.json', 'r', encoding='utf-8') as f:
content = json.loads(f.read())
def to_image():
with open('image.png', 'wb') as f:
f.write(base64.b64decode(list(content['ids'][0].items())[-1][-1].encode('utf-8')))
to_image()
请帮助我重现我的步骤而不出现此错误。
简介
每种格式都有(应该有)自己的“header”和“结束”信号才能知道:
- 它包含什么类型的信息
- 数据开始的地方。
- 结束的地方。
在此处查看 .jpg 文件的“header”和“结尾”结构:JPG Signature Format: Documentation & Recovery Example
为什么存在?它阻止了这里发生的事情……应该有一个“隐藏”代码来检查“header”和“结束”字节是否正确,如果不正确,则数据丢失。然后通过以下方式提醒您:
binascii.Error: Incorrect padding
调试
您在 data.json 中写入的字节数组比图像中的原始字节数组少得多...您正在丢失信息。
观察
我所看到的和我认为的问题是,您正在使用 HTTP 动词 GET 发送大量数据。它有8KB的限制容量。那么如果你的图片比那个大,你就不能用 GET 请求发送它。
在此处查看限制:Maximum length of HTTP GET request
推荐
对于这种情况,使用POST请求发送大于8KB的数据(*使用POST请求不仅限于大小,还有其他情况)
解决方案
有多种方法可以通过 POST 请求发送,请参见此处:MIME types。
发送:
- 一张图片,使用MIME类型
image
- 使用
multipart/form-data
倍增文件
- 你可以用
application/json
发送 JSON
- 使用
text/plain
发送原始文本
参见:How are parameters sent in an HTTP POST request?
Image: Image or graphical data including both bitmap and vector still images as well as animated versions of still image formats such as animated GIF or APNG. Common examples are image/jpeg, image/png, and image/svg+xml.
你可以这样取数据(我想,这只适用于多个文件multipart/form-data
):
face=request.files['face'].read()
也许其他人是:
request.form['face']
request.data['face']
request.get_data['face']
request.get_json['face']
以下是从 POST 请求接收数据的正确方法和不同方法:Get the data received in a Flask request
我有一个名为 'image.png' 的图像,首先我向我的服务器请求将图像保存为 json 文件中的 base64 字符串。
def get_img_content(coding='utf-8'):
with open('image.png', 'rb') as f:
img_data = base64.b64encode(f.read()).decode(coding)
return img_data
requests.get(f'http://127.0.0.1:5000/?face={get_img_content()}')
下面我添加了处理我的请求的服务器代码
from flask import Flask, request
import os
import json
app = Flask(__name__)
if "data.json" not in os.listdir(os.getcwd()):
with open('data.json', 'a', encoding='utf-8') as f:
pass
content = {'ids': [], 'results': []}
else:
with open('data.json', 'r', encoding='utf-8') as f:
content = json.loads(f.read())
def add_id(id, face, content=content):
content['ids'].append({id: face})
with open('data.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(content))
@app.route('/', methods=['GET'])
def main():
face = request.args.get('face')
if not face:
return 'Valid request has to contain face'
id = [int(list(i.keys())[0]) for i in content['ids']]
id = str(max(id) + 1 if id else 1)
add_id(id, face)
print(content)
return id
@app.route('/get', methods=['GET'])
def get():
id = request.args.get('id')
if not id:
return 'Valid request has to contain id'
for i in content['results']:
if list(i.keys())[0] == id:
return json.dumps({'result': i[id]})
return "Couldn't find result"
if __name__ == '__main__':
app.run()
之后我尝试从 data.json 中读取这个 base64 字符串并将其转换为图像,但是我得到了 PaddingError
binascii.Error: 填充不正确
import base64
import json
with open('data.json', 'r', encoding='utf-8') as f:
content = json.loads(f.read())
def to_image():
with open('image.png', 'wb') as f:
f.write(base64.b64decode(list(content['ids'][0].items())[-1][-1].encode('utf-8')))
to_image()
请帮助我重现我的步骤而不出现此错误。
简介
每种格式都有(应该有)自己的“header”和“结束”信号才能知道:
- 它包含什么类型的信息
- 数据开始的地方。
- 结束的地方。
在此处查看 .jpg 文件的“header”和“结尾”结构:JPG Signature Format: Documentation & Recovery Example
为什么存在?它阻止了这里发生的事情……应该有一个“隐藏”代码来检查“header”和“结束”字节是否正确,如果不正确,则数据丢失。然后通过以下方式提醒您:
binascii.Error: Incorrect padding
调试
您在 data.json 中写入的字节数组比图像中的原始字节数组少得多...您正在丢失信息。
观察
我所看到的和我认为的问题是,您正在使用 HTTP 动词 GET 发送大量数据。它有8KB的限制容量。那么如果你的图片比那个大,你就不能用 GET 请求发送它。
在此处查看限制:Maximum length of HTTP GET request
推荐
对于这种情况,使用POST请求发送大于8KB的数据(*使用POST请求不仅限于大小,还有其他情况)
解决方案
有多种方法可以通过 POST 请求发送,请参见此处:MIME types。
发送:
- 一张图片,使用MIME类型
image
- 使用
multipart/form-data
倍增文件
- 你可以用
application/json
发送 JSON
- 使用
text/plain
发送原始文本
参见:How are parameters sent in an HTTP POST request?
Image: Image or graphical data including both bitmap and vector still images as well as animated versions of still image formats such as animated GIF or APNG. Common examples are image/jpeg, image/png, and image/svg+xml.
你可以这样取数据(我想,这只适用于多个文件multipart/form-data
):
face=request.files['face'].read()
也许其他人是:
request.form['face']
request.data['face']
request.get_data['face']
request.get_json['face']
以下是从 POST 请求接收数据的正确方法和不同方法:Get the data received in a Flask request