项目 05 改善上传图片处理

项目 05 改善上传图片处理

  handlers/main.py更新

import tornado.web
import os
from pycket.session import SessionMixin
from utils import photo
from utils.account import add_post_for,get_post_for

class AuthBaseHandler(tornado.web.RequestHandler,SessionMixin):
    def get_current_user(self):
        return self.session.get('tudo_user_info') #拿到的是一个username,在登录的时候以键值对的形式保存username,类似于{'tudo_user_info':'username'}

class IndexHandler(AuthBaseHandler):
    """
    Home page for user,photo feeds 主页
    """
    @tornado.web.authenticated #如果没有登录(拿不到current_user),会自动跳转到 /login ,并把当前url加到next参数里面
    def get(self,*arg,**kwargs):
        posts = get_post_for(self.current_user) #current_user 是获取get_current_user的用户名;然后拿到该用户的图片(是一个列表)
        image_urls = [p.image_url for p in posts]
        self.render('index.html',images = image_urls)

class ExploreHandler(AuthBaseHandler):
    """
    Explore page,photo of other users 
    """
    @tornado.web.authenticated
    def get(self,*arg,**kwargs):
        posts = get_post_for(self.current_user)
        thumb_urls = [p.thumb_url for p in posts]
        self.render('explore.html',images=thumb_urls)

class PostHandler(tornado.web.RequestHandler):
    """
    Single photo page and maybe 单独的照片页
    """
    def get(self,*arg,**kwargs):
        self.render('post.html',post_id = kwargs['post_id'])

class UploadHandler(AuthBaseHandler):
    """
    接收图片上传
    """
    def get(self,*arg,**kwargs):
        self.render('upload.html')

    def post(self, *args, **kwargs):
        img_files = self.request.files.get('newimg',None)
        for img in img_files:
            saver = photo.ImageSave(self.settings['static_path'],img['filename']) #Image类的实例化
            saver.save_upload(img['body']) #保存上传图片
            saver.make_thumb() #进行图片缩略并保存
            add_post_for(self.current_user,saver.upload_url,saver.thumb_url) #添加图片和缩略图的路径到服务器

        self.redirect('/explore')

  utils/photo.py更新

import glob
import os
from PIL import Image

def get_images(path):
    '''
    某个路径下所有的文件会返回成一个列表
    '''
    images = []
    for file in glob.glob(path+'/*.jpg'):#所有目录下面为*.jpg的所有图片,
        images.append(file)
    return images

class ImageSave(object):
    '''
    辅助保存用户上传的图片,生成缩略图,保存图片相关URL用来存到数据库
    '''

    upload_dir = 'uploads'
    thumb_dir = 'thumbs'
    size = (200,200)

    def __init__(self,static_path,name):
        '''
        记录 应用保存图片的文件路径
        :param static_path: 图片保存到服务器文件的路径
        :param name: 用户上传的图片名字
        '''
        self.static_path = static_path
        self.name = name

    @property #将方法变为属性,有了这个,下面需要调用这个地址的时候不需要 upload_url() 了,直接可以用upload_url
    def upload_url(self):
        '''
        该地址是给web服务器的 ,也就是本地路径,image的本地目录
        '''
        return os.path.join(self.upload_dir,self.name)

    @property
    def upload_path(self):
        '''
        该地址是给文件系统的,也就是保存路径,保存路径为虚拟机路径加本地目录
        '''
        return os.path.join(self.static_path,self.upload_url)

    def save_upload(self,content):
        '''
        保存上传图片
        :param content:
        :return:
        '''
        with open(self.upload_path,'wb') as f:
            f.write(content)

    @property
    def thumb_url(self):
        '''
        缩略图路径
        :return:缩略图路径
        '''
        base, _ = os.path.splitext(self.name) #分离文件名和后缀,一般后面的后缀用不到就用 _ 来表示
        thumb_name = os.path.join('{0}_{1}x{2}.jpg'.format(base,self.size[0],self.size[1])) #缩略图的名字
        return os.path.join(self.upload_dir,self.thumb_dir,thumb_name) #返回缩略图的路径,静态文件目录/简略图目录/文件名

    def make_thumb(self):
        '''
        制作缩略图
        :return:
        '''
        im = Image.open(self.upload_path) #打开图片保存目录下的该图片文件
        im.thumbnail(self.size) #缩略成指定的大小
        im.save(os.path.join(self.static_path,self.thumb_url),"JPEG") #以JPEG格式保存在指定目录下,static_path/简略图路径

  

原文地址:https://www.cnblogs.com/xuchengcheng1215/p/9187125.html