一、前言
在现代 Web 应用程序中,经常需要上传、显示图片。但是,过多的图片会增加服务器的负担,也会占用用户的带宽。为了达到更好的用户体验,我们需要在上传图片的同时实现对图片的压缩。
本文将介绍 Django 框架如何实现前端图片压缩功能的方法。
二、前端图片压缩
前端图片压缩指的是在使用 JavaScript 等前端语言进行图片处理。前端图片压缩可大大减少图片的大小,使我们可以更快地将图片加载到页面上,从而提高网站的性能。
常见的前端图片压缩方法有:
HTML5 增加了一个新特性 Blob 对象,可以使我们在客户端进行图片压缩。
下面是一个 HTML5 压缩图片的示例:
<input type="file" accept="image/*" onchange="compress(this.files[0])"/>
<script>
function compress(source_img_obj) {
var mime_type = "image/jpeg";
var quality = 0.5;
var cvs = document.createElement('canvas');
var ctx = cvs.getContext("2d");
cvs.width = source_img_obj.width;
cvs.height = source_img_obj.height;
ctx.drawImage(source_img_obj, 0, 0);
var newImageData = cvs.toDataURL(mime_type, quality);
var result_image_obj = new Image();
result_image_obj.src = newImageData;
return result_image_obj;
}
</script>
前端图片处理库很多,这里介绍两个常用的库:ImageJS 和 PicaJS。
ImageJS 提供了一些常用的图片处理方法,如:旋转、缩放、剪切等。
PicaJS 是一个高质量的图片处理库,可以在客户端对图片进行缩放、调整质量等操作。PicaJS 有一个很方便的方法,能够自动根据图片尺寸和质量进行压缩。
三、Django 中实现前端图片压缩
对于 Django 程序员来说,使用 HTML5 自带的压缩或者第三方库都可以实现图片压缩,但是这些压缩方法都需要使用 JavaScript 进行实现。如果我们需要将压缩后的图片已表单的形式提交给 Django 后端,则需要注意一些问题。
以下是使用第三方库 PicaJS,压缩图片并上传到 Django 后端的示例程序:
from django import forms
class ImgForm(forms.Form):
img = forms.ImageField(label='图片')
class Meta:
fields = ['img']
from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
from django.conf import settings
import os
from .forms import ImgForm
def compress(request):
if request.method == 'POST':
form = ImgForm(request.POST, request.FILES)
if form.is_valid():
img = request.FILES['img']
filename = img.name
file_path = os.path.join(settings.MEDIA_ROOT, filename)
# 保存上传的图片
storage = FileSystemStorage()
storage.save(file_path, img)
# 使用 PicaJS 进行压缩
from io import BytesIO
import pica
import base64
# 读取上传的文件
img_data = BytesIO()
for chunk in img.chunks():
img_data.write(chunk)
# 将上传的文件转为 base64 编码
img_b64 = base64.b64encode(img_data.getvalue()).decode('utf-8')
# 使用 PicaJS 进行压缩
img_bin = pica.compress(img_b64, {
"quality": 0.5,
"maxOutputSize": 1024 * 1024 # 最大压缩后大小,这里设置为 1M
})
# 将压缩后的文件保存到本地
compressed_filename = 'compressed_' + filename
compressed_file_path = os.path.join(settings.MEDIA_ROOT, compressed_filename)
with open(compressed_file_path, 'wb') as f:
f.write(base64.b64decode(img_bin))
# 将压缩后的文件保存到表单中
form.data['img'] = open(compressed_file_path, 'rb')
return render(request, 'compress.html', {
'form': form,
'compressed_file_path': compressed_file_path
})
else:
form = ImgForm()
return render(request, 'compress.html', {'form': form})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片压缩示例</title>
</head>
<body>
<form action="{% url 'compress' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit">提交</button>
</form>
{% if compressed_file_path %}
<hr>
<h3>压缩后的图片:</h3>
<img src="{{ compressed_file_path }}" alt="">
{% endif %}
</body>
</html>
注意:由于我们使用的是 PicaJS 进行压缩,因此需要在模板文件中引入该库:
<script src="https://cdn.jsdelivr.net/npm/pica/dist/pica.min.js"></script>
四、小结
本文简要介绍了 Django 中如何实现前端图片压缩功能的方法。如果您在开发 Web 应用程序时,需要实现图片压缩功能,可以根据本文提供的方法进行开发。