无法解码 base64 编码的图像
Not able to decode base64 encoded image
我是 python 的新手。我的任务是构建一个 API 端点,该端点拍摄图像并 returns 图像。所以,我选择 flask
来完成我的工作。
我遵循了这个 SO 问题 - 用于 API 端点上传图像文件。
代码如下:
from flask import Flask, render_template , request , jsonify
from PIL import Image
import os , io , sys
import numpy as np
import cv2
import base64
app = Flask(__name__)
start_point = (0, 0)
end_point = (110, 110)
color = (255, 0, 0)
thickness = 2
@app.route('/image' , methods=['POST'])
def mask_image():
file = request.files['image'].read()
npimg = np.fromstring(file, np.uint8)
img = cv2.imdecode(npimg,cv2.IMREAD_COLOR)
img = Image.fromarray(img.astype("uint8"))
rawBytes = io.BytesIO()
img.save(rawBytes, "png")
rawBytes.seek(0)
img_base64 = base64.b64encode(rawBytes.read())
return jsonify({'status':str(img_base64)})
if __name__ == '__main__':
app.run(debug = True)
然后我使用 python requests file upload 向 API 发送了一个请求。
但我无法解码 base64 响应。我试过的代码
import requests
import base64
files = {'image': open('image.png','rb')}
r = requests.post("http://localhost:5000/image", files=files)
print(base64.decodestring(r.text))
但是它抛出一个错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~/anaconda3/envs/py37/lib/python3.7/base64.py in _input_type_check(s)
509 try:
--> 510 m = memoryview(s)
511 except TypeError as err:
TypeError: memoryview: a bytes-like object is required, not 'str'
The above exception was the direct cause of the following exception:
TypeError Traceback (most recent call last)
<ipython-input-192-e8ba5f9daae3> in <module>
----> 1 base64.decodestring(r.text)
~/anaconda3/envs/py37/lib/python3.7/base64.py in decodestring(s)
552 "use decodebytes()",
553 DeprecationWarning, 2)
--> 554 return decodebytes(s)
555
556
~/anaconda3/envs/py37/lib/python3.7/base64.py in decodebytes(s)
543 def decodebytes(s):
544 """Decode a bytestring of base-64 data into a bytes object."""
--> 545 _input_type_check(s)
546 return binascii.a2b_base64(s)
547
~/anaconda3/envs/py37/lib/python3.7/base64.py in _input_type_check(s)
511 except TypeError as err:
512 msg = "expected bytes-like object, not %s" % s.__class__.__name__
--> 513 raise TypeError(msg) from err
514 if m.format not in ('c', 'b', 'B'):
515 msg = ("expected single byte elements, not %r from %s" %
TypeError: expected bytes-like object, not str
如何解码图像?
尝试 r.content
,它是字节而不是 r.text
,它是字符串。
两件事,首先base64.decodestring
expects bytes, not a string. You need to use either r.content
or r.text.encode('utf8')
to obtain bytes. As well, decodestring
is deprecated, so you shouldn't use that. Typically, unless you have a good reason not to do so, you should use base64.b64decode
解码base64数据。
其次,/image
端点 returns 包含 base64 图像的 JSON 对象。您的客户端必须首先从 JSON 响应中提取图像数据,然后对其进行解码。 response
对象包含对此有用的 .json()
方法:
import requests
import base64
files = {'image': open('image.png','rb')}
r = requests.post("http://localhost:5000/image", files=files)
print(base64.b64decode(r.json()['status']))
标记的答案是我自己的。因此,我会提供答案。
其中一位网友@ToxicCode 已经给出了99%的答案。但这里有一个问题。该脚本将响应作为字节字符串发送,包裹在如下所示的字符串中。
"b'iVBORw0KGgoAAAANSUhEUgAABXYAAAOOCAIAAAAru93tAAEAAElEQVR4nOz9eZRk+V3ffX5+98a+ZkbutbZ2gZAx6DFgsEGHHRtrsC0xFgezGGg3to8H2+NlQGjmSAI/D4wfGD/40AiZRTDgBwkMGI9AwjoCzGLZgLHYZEmou5bMjFwiMjPWu37nj4iqzOqur
...
..
字节 b
已经存在于字符串中。因此,如果您遵循@ToxicCode 不注意这一点,您将面临错误。因此,作为一种糟糕的方法,您可以使用 ast.literal_eval
转换为字符串,然后遵循 @ToxicCode 代码。
重要提示:不要在生产服务器中使用ast.literal_eval()
。相应地更改实施。
import ast
import requests
import base64
files = {'image': open('image.png','rb')}
r = requests.post("http://localhost:5000/image", files=files)
data = ast.literval_eval(r.json()['status'])
print(base64.b64decode(data))
我是 python 的新手。我的任务是构建一个 API 端点,该端点拍摄图像并 returns 图像。所以,我选择 flask
来完成我的工作。
我遵循了这个 SO 问题 -
代码如下:
from flask import Flask, render_template , request , jsonify
from PIL import Image
import os , io , sys
import numpy as np
import cv2
import base64
app = Flask(__name__)
start_point = (0, 0)
end_point = (110, 110)
color = (255, 0, 0)
thickness = 2
@app.route('/image' , methods=['POST'])
def mask_image():
file = request.files['image'].read()
npimg = np.fromstring(file, np.uint8)
img = cv2.imdecode(npimg,cv2.IMREAD_COLOR)
img = Image.fromarray(img.astype("uint8"))
rawBytes = io.BytesIO()
img.save(rawBytes, "png")
rawBytes.seek(0)
img_base64 = base64.b64encode(rawBytes.read())
return jsonify({'status':str(img_base64)})
if __name__ == '__main__':
app.run(debug = True)
然后我使用 python requests file upload 向 API 发送了一个请求。
但我无法解码 base64 响应。我试过的代码
import requests
import base64
files = {'image': open('image.png','rb')}
r = requests.post("http://localhost:5000/image", files=files)
print(base64.decodestring(r.text))
但是它抛出一个错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~/anaconda3/envs/py37/lib/python3.7/base64.py in _input_type_check(s)
509 try:
--> 510 m = memoryview(s)
511 except TypeError as err:
TypeError: memoryview: a bytes-like object is required, not 'str'
The above exception was the direct cause of the following exception:
TypeError Traceback (most recent call last)
<ipython-input-192-e8ba5f9daae3> in <module>
----> 1 base64.decodestring(r.text)
~/anaconda3/envs/py37/lib/python3.7/base64.py in decodestring(s)
552 "use decodebytes()",
553 DeprecationWarning, 2)
--> 554 return decodebytes(s)
555
556
~/anaconda3/envs/py37/lib/python3.7/base64.py in decodebytes(s)
543 def decodebytes(s):
544 """Decode a bytestring of base-64 data into a bytes object."""
--> 545 _input_type_check(s)
546 return binascii.a2b_base64(s)
547
~/anaconda3/envs/py37/lib/python3.7/base64.py in _input_type_check(s)
511 except TypeError as err:
512 msg = "expected bytes-like object, not %s" % s.__class__.__name__
--> 513 raise TypeError(msg) from err
514 if m.format not in ('c', 'b', 'B'):
515 msg = ("expected single byte elements, not %r from %s" %
TypeError: expected bytes-like object, not str
如何解码图像?
尝试 r.content
,它是字节而不是 r.text
,它是字符串。
两件事,首先base64.decodestring
expects bytes, not a string. You need to use either r.content
or r.text.encode('utf8')
to obtain bytes. As well, decodestring
is deprecated, so you shouldn't use that. Typically, unless you have a good reason not to do so, you should use base64.b64decode
解码base64数据。
其次,/image
端点 returns 包含 base64 图像的 JSON 对象。您的客户端必须首先从 JSON 响应中提取图像数据,然后对其进行解码。 response
对象包含对此有用的 .json()
方法:
import requests
import base64
files = {'image': open('image.png','rb')}
r = requests.post("http://localhost:5000/image", files=files)
print(base64.b64decode(r.json()['status']))
标记的答案是我自己的。因此,我会提供答案。
其中一位网友@ToxicCode 已经给出了99%的答案。但这里有一个问题。该脚本将响应作为字节字符串发送,包裹在如下所示的字符串中。
"b'iVBORw0KGgoAAAANSUhEUgAABXYAAAOOCAIAAAAru93tAAEAAElEQVR4nOz9eZRk+V3ffX5+98a+ZkbutbZ2gZAx6DFgsEGHHRtrsC0xFgezGGg3to8H2+NlQGjmSAI/D4wfGD/40AiZRTDgBwkMGI9AwjoCzGLZgLHYZEmou5bMjFwiMjPWu37nj4iqzOqur
...
..
字节 b
已经存在于字符串中。因此,如果您遵循@ToxicCode 不注意这一点,您将面临错误。因此,作为一种糟糕的方法,您可以使用 ast.literal_eval
转换为字符串,然后遵循 @ToxicCode 代码。
重要提示:不要在生产服务器中使用ast.literal_eval()
。相应地更改实施。
import ast
import requests
import base64
files = {'image': open('image.png','rb')}
r = requests.post("http://localhost:5000/image", files=files)
data = ast.literval_eval(r.json()['status'])
print(base64.b64decode(data))