[英]Uploading Image in Django: 'utf-8' codec can't decode byte 0x89 in position 246: invalid start byte
I'm trying to upload images in my api using pure json, but when i tried to upload image in request.Files and the token in request.body, I face this error:我正在尝试使用纯 json 在我的 api 中上传图像,但是当我尝试在 request.Files 中上传图像和 request.body 中的令牌时,我遇到了这个错误:
UnicodeDecodeError at /api/auth/set-profile-image/
'utf-8' codec can't decode byte 0x89 in position 246: invalid start byte
and it says:它说:
Unicode error hint
The string that could not be encoded/decoded was: " �PNG
but i'm sending JPG!但我正在发送 JPG! :D
:D
View.py查看.py
@csrf_exempt
def set_profile_image(request):
if request.method == 'POST':
request_info = json.loads(request.body)
token = request_info.get('token')
img = request.FILES['image']
if token is not None and img is not None:
user = User.objects.filter(token=token)
if user.exists():
user = user.get()
form = UploadImage(request.POST, request.FILES['image'])
if form.is_valid():
user.profile_image = form.cleaned_data['image']
user.save()
response = {
'status_code': 200,
'image_set': True,
'image_url': user.profile_image.url
}
Form.py表单.py
from django import forms
class UploadImage(forms.Form):
image = forms.ImageField()
and my test code is:我的测试代码是:
import requests
data = {
'token': 'helloworld1--_aFsV-ZVG9lVpi0KSydrx3pG3TSMPqqHVKWD2Yc8bE'
}
url = 'http://localhost:8000/api/auth/set-profile-image/'
with open('test.jpg', 'rb') as img:
response = requests.post(
url=url,
data=data,
files={
'image': img
}
)
# print(response.text)
f = open('test.html', 'wb')
f.write(response.content)
f.close()
I'm using ImageField
as my db field in models.py我在 models.py 中使用
ImageField
作为我的数据库字段
Warmest Regards, Poor Maintenance guy who's stuck in others code!最热烈的问候,可怜的维护人员,他被困在其他代码中!
Images are going to contain data which is not safe to represent in UTF-8.图像将包含用 UTF-8 表示不安全的数据。 If you need to transport image data this way, you should encode it into something else first which is safe in UTF-8, such as base64.
如果您需要以这种方式传输图像数据,您应该首先将其编码为其他在 UTF-8 中安全的内容,例如 base64。
To do this in your Python sender, you can use something like base64.b64encode(img)
要在您的 Python 发件人中执行此操作,您可以使用类似
base64.b64encode(img)
And to decode it again on the other side, you will need to use base64.b64decode(img)
要在另一侧再次解码,您需要使用
base64.b64decode(img)
Ok after some tests and thanks to Jacob See's answer, i found a solution:好的,经过一些测试并感谢 Jacob See 的回答,我找到了一个解决方案:
First I encode my image to base64 and sent it through the API like this:首先,我将图像编码为 base64 并通过 API 发送,如下所示:
with open('test.jpg', 'rb') as img:
data = {
"token": "some token"
}
response = requests.post(
url=url,
data={
'data': json.dumps(data),
'image': b64encode(img.read())
}
)
And in my API i do this:在我的 API 中,我这样做:
new_base64_img = request.POST.get('image', None)
try:
image = Image.open(BytesIO(b64decode(new_base64_img)))
image_content = ContentFile(b64decode(new_base64_img))
file_name = "some file name" + image.format
user.profile_image.save(file_name, image_content, save=True)
return JsonResponse({"OK"})
except IOError:
return JsonResponse({"Image should be base64 encoded!"})
Problem Solved :D问题已解决:D
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.