项目 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/简略图路径