flask在开发微信公众号或者小程序时会涉及到手机端上传图片以及生成缩略图的需求(注意,一般涉及到图文都是把图片和文字分开储存到两张表中,用外键作为连接)
第一步, 将本地图片上传
1、前端模板:
<div class="weui-gallery" id="gallery">
<span class="weui-gallery__img" id="galleryImg"></span>
<div class="weui-gallery__opr">
<a href="javascript:" class="weui-gallery__del">
<i class="weui-icon-delete weui-icon_gallery-delete"></i>
</a>
</div>
</div>
# 此段gallery用于生成手机端的点击全屏预览效果
<div class="weui-cell">
<div class="weui-cell__bd">
<div class="weui-uploader">
<div class="weui-uploader__hd">
<p class="weui-uploader__title" style="color:#9B9B9B;">图片(至少一张)</p>
</div>
<div class="weui-uploader__bd">
<ul class="weui-uploader__files" id="uploaderFiles">
</ul>
<div class="weui-uploader__input-box ">
<input id="uploaderInput" class="weui-uploader__input zjxfjs_file" type="file" accept="image/*" multiple="">
</div>
</div>
</div>
</div>
</div>
# 此段动态上传图片
注:这是基于微信weui框架样式的上传图片,网页版只需要<input type="file"即可>;
2、jquery和ajax调取手机相册以及发送数据到后台:
var src, url = window.URL || window.webkitURL || window.mozURL,
files = e.target.files;
for(var i = 0, len = files.length; i < len; ++i) {
var file = files[i];
if(url) {
src = url.createObjectURL(file);
} else {
src = e.target.result;
}
jQuery.showLoading("正在压缩图片");
var formData = new FormData();
var notice_id = Number($('.weui-cells_form').attr('id'));
formData.append('notice_id' , notice_id);
formData.append('uploadImage', $uploaderInput[0].files[0]);
jQuery.ajax({
type:"POST",
url: '{{ url_for('main.upload_images') }}',
data:formData,
dataType:'json',
contentType: false,
processData: false,
cache:false,
success: function(data) {
jQuery.hideLoading();
},
error: function() {
jQuery.hideLoading();
jQuery.alert('服务器繁忙,上传图片失败', function () {
$('.weui-mask').fadeOut(200);
});
}
});
var tmpl_new = tmpl.replace('#index#', image_index);
$uploaderFiles.append($(tmpl_new.replace('#url#', src)));
}
});
var index; //第几张图片
$uploaderFiles.on("click", "li", function() {
index = $(this).index();
$galleryImg.attr("style", this.getAttribute("style"));
$gallery.fadeIn(100);
});
$gallery.on("click", function() {
$gallery.fadeOut(100);
});
//删除图片
$(".weui-gallery__del").click(function() {
var image_id = $uploaderFiles.find("li").eq(index).attr("id");
var formData = new FormData();
formData.append('index', image_id);
jQuery.ajax({
type:"POST",
url: '{{ url_for('main.delete_images') }}',
data:formData,
dataType:'json',
contentType: false,
processData: false,
cache:false,
success: function(data) {
jQuery.hideLoading();
$uploaderFiles.find("li").eq(index).remove();
},
error: function() {
jQuery.hideLoading();
jQuery.alert('服务器繁忙,删除图片失败', function () {
$('.weui-mask').fadeOut(200);
});
}
});
3、后台接收图片并上传:
def upload_images():
if request.method == 'POST':
image_time = str(datetime.now()).replace("-", "").replace(":", "").replace(" ", "")
upload_image = request.files['uploadImage']
# basepath = os.path.dirname(__file__) # 当前文件所在路径
upload_path = os.path.join('./app/static/uploads/',
image_time + secure_filename(upload_image.filename)) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径,并且一定要加入上传时间作为图片的唯一路径标识,否则会导致图片路径重复
return jsonify({'data': 1})
return jsonify({'data': 0})
4、有时候手机相册的图片往往动辄几MB,这样在网页回显的时候网页加载速度会特别慢,往往每上传一张图片就会为其生成一张缩略图,并将所有缩略图单独存放在一个thub文件夹下,生成缩略图代码如下:
import os
from PIL import Image # 要先安装pillow包
# 单个图片生成缩略图
def image_size_off(path):
im = Image.open(path)
box = clipimage(im.size)
region = im.crop(box)
size = (100, 70)
region.thumbnail(size, Image.ANTIALIAS)
# 这里保存thumbnail以后的结果
name = 'thub_' + path.lstrip('./app/static/uploads/').rstrip('.jpg').rstrip('.JPG').rstrip('.PNG').rstrip('.png') + '.jpg'
region.save(
os.path.join("./app/static/thub/", name))
# 取宽和高的值小的那一个来生成裁剪图片用的box, 并且尽可能的裁剪出图片的中间部分
def clipimage(size):
width = int(size[0])
height = int(size[1])
if width > height:
dx = width - height
box = (dx / 2, 0, height + dx / 2, height)
else:
dx = height - width
box = (0, dx / 2, width, width + dx / 2)
return box
def create_img_url(url):
return 'static/thub/' + 'thub_' + url.lstrip('static/uploads/').rstrip('.jpg').rstrip(
'.JPG').rstrip('.png').rstrip('.PNG') + '.jpg'
然后在views.py里面调用函数即可:
image_size_off(upload_path) # 生成缩略图
# 附加参考: 将文件夹下的图片批量压缩成缩略图并储存到文件夹下
# def image_size_all():
# rootDir = './app/static/uploads/'
# for lists in os.listdir(rootDir):
# path = os.path.join(rootDir, lists)
# im = Image.open(path)
# box = clipimage(im.size)
# region = im.crop(box)
# size = (100, 70)
# region.thumbnail(size, Image.ANTIALIAS)
# # 这里保存thumbnail以后的结果
# if lists[lists.rfind('.'):].lower() == '.jpg':
# name = 'thub_' + lists
# else:
# name = 'thub_' + lists + '.jpg'
# print(name)
# region.save(
# os.path.join("./app/static/thub/", name))