django从mongodb取二进制PIL压缩后json传输python BytesIo

需求背景:Python3.6.7+django+PIL+Mongodb    django开放一个图片下载接口,因为图片大小为10+M,所以要后端压缩后再返回给前端。

解决问题思路:图片存在mongodb中,以二进制的形式存储,django获取到二进制,PiL读取,压缩,返回压缩后的二进制,转为base64,json形式返回给前端

话不多说,上代码,先普及一下python中二进制内存中存储方法

# 如果要操作二进制数据,就需要使用BytesIO。

# BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes


from io import BytesIO

fb = BytesIO()
fb.write("中国".encode("utf-8"))
fb.write("美丽".encode("utf-8"))
print(fb.getvalue().decode("utf-8"))
# 中国美丽
fb.close()

# 像读文件一样读取
fb1 = BytesIO("中国".encode("utf-8"))
print(fb1.read())
# b'\xe4\xb8\xad\xe5\x9b\xbd'
fb1.close()


重点来了,图片缩放

class PostDownloadImage(APIView):
    authentication_classes = [Authentication, ]  # 启动token验证

    def post(self, request):
        fileName = request.data.get('fileName')
        print("准备下载", fileName)
        try:
            client = MongoClient('mongodb://{0}:{1}@{2}:{3}'.format(
                Mongodb_account, Mongodb_pass, MongodbIP, MongodbPort))
            db = client[DataBase_image]
            gridfs_col = GridFS(db, collection='image')
            file_data_bytes = gridfs_col.get_version(filename=fileName).read()
            # file_data_str = base64.b64encode(file_data_bytes).decode('ascii')  # 二进制流解码成字符串
            # with open(out_name, 'wb') as file_w:
            #     file_w.write(file_data)
            read_byte_io = BytesIO(file_data_bytes)  # 新建IO通道
            image = Image.open(read_byte_io)
            width = image.width 
            height = image.height
            
            rate = 1.0 # 压缩率

            # 根据图像大小设置压缩率
            if width >= 2000 or height >= 2000:
                rate = 0.3
            elif width >= 1000 or height >= 1000:
                rate = 0.5
            elif width >= 500 or height >= 500:
                rate = 0.9    

            width = int(width * rate)   # 新的宽
            height = int(height * rate) # 新的高

            image.thumbnail((width, height), Image.ANTIALIAS) # 生成缩略图
            # image对象转为二进制
            imgByteArr = BytesIO()
            image.save(imgByteArr,format="PNG")
            result_bytes = imgByteArr.getvalue()
            imgByteArr.close()  # 关闭byteio
            read_byte_io.close()  # 关闭IO通道
            file_data_str = base64.b64encode(result_bytes).decode('ascii')  # 二进制流解码成字符串
            ret = {'code': 1000, 'msg': None, "rate": rate, "result": file_data_str}
            print("下载成功", fileName)
        except Exception as e:
            print(e)
            ret = {'code': 1001, 'msg': '图片下载失败', 'result': None}
            print("下载失败", fileName)
        return JsonResponse(ret)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值