tornado图片上传与下载,Android客户端

本文介绍了Android客户端如何将Bitmap转换为jpg字节数组并加密成JSON字符串发送至Python Tornado服务端进行图片保存。服务端通过解密并保存为jpg文件。下载时,利用PIL库读取图片数据,写入BytesIO。另外,文中还提供了2020年4月9日更新的简单图片下载方法,包括参考StaticFileHandler和设置静态文件路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android客户端,将我们的通用的bitmap转为jpg字节数组:

    static byte[] compress(final Bitmap bitmap) {
        if(bitmap == null){
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, QUALILY, out);
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

然后,我们通过Base64.encodeToString将这个数据加密成一个字符串,就可以当作json的一项作为jsonstring发送给服务端。

Python服务端,解密然后保存到jpg文件即可:
而下载文件更简单,使用PIL.Image,可以读出imagedata,然后写到BytesIO中即可。
服务端的读写代码如下:

from abc import ABC
from tornado.web import RequestHandler
from libs.hooks import check_token
from libs.encode import Encode
import time
import io
from PIL import Image
from settings.config import max_img_size


class ImageHandler(RequestHandler, ABC):
    async def get(self, *args, **kwargs):
        url = self.request.uri
        if url.startswith("/image/") and url.endswith(".jpg"):
            file_name = 'static/upload/{}'.format(url[7:])
            await self.download(file_name)
            pass
        else:
            self.write("Invalid path ")
            self.write_error(404)

    @check_token
    async def post(self):
        url = self.request.uri
        token = self.get_body_argument('token')
        if url.startswith("/image/upload"):
            image = self.get_body_argument('image')
            image_data = Encode.decode(image)
            ut = int(time.time())
            file_name = token + str(ut) + ".jpg"
            save_to = 'static/upload/{}'.format(file_name)
            await self.upload(image_data, save_to)
        self.write_error(404)

    async def download(self, file_name):
        try:
            img = Image.open(file_name)
            height = img.size[1]
            width = img.size[0]
            while (height > max_img_size) or (width > max_img_size):
                height = height//2
                width = width//2
                print(width, height)
            img = img.resize((width, height))
        except FileNotFoundError:
            self.write_error(404)
            return
        bio = io.BytesIO()
        img.save(bio, "PNG")
        self.set_header('Content-Type', 'image/PNG')
        self.write(bio.getvalue())
        pass

    @staticmethod
    async def upload(image_data, save_to):
        with open(save_to, 'wb') as f:
            f.write(image_data)

路由

 (r'/image/(.*)', ImageHandler),

2020年4月9日,补充更简单的图片下载方式:
1)参考StaticFileHandler的get方法:

    async def download(self, file_name):
        try:
            pic = open(file_name, "rb")
        except FileNotFoundError:
            self.write_error(404)
            return
        self.write(pic.read())
        self.set_header('Content-Type', 'image/png')
        pass

注意要以rb方式打开。

2)设置静态文件路径:

(r'/image/(.*)', StaticFileHandler,
     {"path": os.path.join(os.path.dirname(__file__), "../static/upload"), "default_filename": "default.jpg"}),

第二中方法的缺点是谁都可以下载,没法check。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值