简介:我有一则帖子,用户最多可以上传8张图片。我的部署方法不允许总上传量(所有图像的总和超过10mb)。因此,我不能使用枕形或其他在upoad之后减小图像尺寸的软件包。我在想,如果我使用JavaScript,则可以在提交表单之前减小图片大小。这样,当我点击提交时,图像已经被缩小,并且所有图像的总数都小于9mb(为了安全起见)
该代码是从以下网站借来的:
使用https://github.com/josefrichter/resize/blob/master/public/preprocess.js
我不确定如何使用它们。以下是我的表单模板
这仅用于我的主要post_image,我仍然必须弄清楚如何减小表单集图像的大小
{% extends 'posts/post_base.html' %}
{% load bootstrap3 %}
{% load staticfiles %}
{% block postcontent %}
<h2> Add a new Post</h2>
<form action="" method="post" enctype="multipart/form-data" id="form">
{% csrf_token %}
{% bootstrap_form form %}
<img id="preview" src="" width="100" />
{{formset.management_form}}
{% for f in formset %}
<div style="border-style: inset; padding:20px;">
<p class="text-warning">Extra Image {{forloop.counter}}</p>
{% bootstrap_form f %}
<img src="" width="60" id="preview-extra{{forloop.counter}}"/>
</div>
{% endfor %}
<br/><br/><input type="submit" class="btn btn-primary" value="Post"/>
</form>
<script >
var fileinput = document.getElementById('fileinput');
var max_width = 500;
var max_height = 500;
var preview = document.getElementById('preview');
var form = document.getElementById('form');
function processfile(file) {
if( !( /image/i ).test( file.type ) )
{
alert( "File "+ file.name +" is not an image." );
return false;
}
// read the files
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (event) {
// blob stuff
var blob = new Blob([event.target.result]); // create blob...
window.URL = window.URL || window.webkitURL;
var blobURL = window.URL.createObjectURL(blob); // and get it is URL
// helper Image object
var image = new Image();
image.src = blobURL;
//preview.appendChild(image); // preview commented out, I am using the canvas instead
image.onload = function() {
// have to wait till it is loaded
var resized = resizeMe(image); // send it to canvas
var newinput = document.createElement("input");
newinput.type = 'hidden';
newinput.name = 'images[]';
newinput.value = resized; // put result from canvas into new hidden input
form.appendChild(newinput);
}
};
}
function readfiles(files) {
// remove the existing canvases and hidden inputs if user re-selects new pics
var existinginputs = document.getElementsByName('images[]');
var existingcanvases = document.getElementsByTagName('canvas');
// it is a live list so removing the first element each time DOMNode.prototype.remove = function() {this.parentNode.removeChild(this);}
while (existinginputs.length > 0) {
form.removeChild(existinginputs[0]);
preview.removeChild(existingcanvases[0]);
}
for (var i = 0; i < files.length; i++) {
processfile(files[i]); // process each file at once
}
fileinput.value = ""; //remove the original files from fileinput
// TODO remove the previous hidden inputs if user selects other files
}
// this is where it starts. event triggered when user selects files
fileinput.onchange = function(){
if ( !( window.File && window.FileReader && window.FileList && window.Blob ) ) {
alert('The File APIs are not fully supported in this browser.');
return false;
}
readfiles(fileinput.files);
};
// === RESIZE ====
function resizeMe(img) {
var canvas = document.createElement('canvas');
var width = img.width;
var height = img.height;
// calculate the width and height, constraining the proportions
if (width > height) {
if (width > max_width) {
//height *= max_width / width;
height = Math.round(height *= max_width / width);
width = max_width;
}
} else {
if (height > max_height) {
//width *= max_height / height;
width = Math.round(width *= max_height / height);
height = max_height;
}
}
// resize the canvas and draw the image data into it
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
preview.appendChild(canvas); // do the actual resized preview
return canvas.toDataURL("image/jpeg",0.7); // get the data from canvas as 70% JPG (can be also PNG, etc.)
}
</script>
{% endblock %}
我希望图像尺寸减小到400kb。如果用户上传的内容少于该数量,则无需调整大小
尝试解决以下错误
答案 0 :(得分:1)
下面的代码可帮助您解决此问题:
views.py:
import re
import io
import base64
from django.core.files import File
from django.shortcuts import render
from .forms import StoreImageForm
def upload_canvas(request):
form = StoreImageForm()
if request.method == 'POST':
image_base64 = request.POST.get('image_base64', '')
res = re.match(r'^([^,]*),(.*)$', image_base64)
if res:
ext = re.match(r'^data:image/(.+);base64$', res.groups()[0]).groups()[0]
image = base64.b64decode(res.groups()[-1])
buf = io.BytesIO(image)
form = StoreImageForm(files={'upload_file': File(buf, name=f'name.{ext}')})
try:
form.is_valid()
except Exception as err:
return render(request, 'form.html', {'message': err, 'form': form})
instance = form.save()
return render(request, 'form.html', {'message': 'Image Uploaded Successfuly', 'form': form})
return render(request, 'form.html', {'message': 'Image Upload Failed', 'form': form})
return render(request, 'form.html', {'message': 'Upload Image...', 'form': form})
form.html:
<html>
<head>
<title>Upload Canvas</title>
<script lang="javascript">
function resize_image(event) {
var canvas = document.getElementById("my_canvas");
var ctx = canvas.getContext("2d");
var reader = new FileReader();
var img = new Image();
var type = '';
var ratio = 1;
img.onerror = function(e) {
console.log("Not ok", e);
}
img.onload = function (img_onload_event) {
canvas.height = canvas.width * (img.height / img.width);
// step 1 - resize to 50%
var oc = document.createElement('canvas'),
octx = oc.getContext('2d');
oc.width = img.width * ratio;
oc.height = img.height * ratio;
octx.drawImage(img, 0, 0, oc.width, oc.height);
// step 2
octx.drawImage(oc, 0, 0, oc.width, oc.height);
// step 3, resize to final size
ctx.drawImage(oc, 0, 0, oc.width, oc.height, 0, 0, canvas.width, canvas.height);
var dataURL = oc.toDataURL(type, ratio)
// var blob = dataURItoBlob(dataURL)
b64 = dataURL;
padding = (b64.charAt(b64.length - 2) === '=') ? 2 : ((b64.charAt(b64.length - 1) === '=') ? 1 : 0);
fileSize = (b64.length * 0.75 - padding) / 1024;
if(fileSize > 500) {
img.src = b64;
return;
}
var my_image_base64 = document.getElementById('my_image_base64')
my_image_base64.setAttribute("value", dataURL)
}
reader.onload = function (e) {
b64 = reader.result;
padding = (b64.charAt(b64.length - 2) === '=') ? 2 : ((b64.charAt(b64.length - 1) === '=') ? 1 : 0);
fileSize = (b64.length * 0.75 - padding) / 1024;
if(fileSize > 500){
ratio = 0.8
}
img.src = e.target.result;
}
type = event.target.files[0].type || 'image/jpeg';
reader.readAsDataURL(event.target.files[0]);
}
window.onload = function(){
document.getElementById('my_image').addEventListener('change', resize_image, false);
}
</script>
</head>
<body>
<h2>{{ message }}</h2>
<form method="post">
{% csrf_token %}
<input type="file" id="my_image" />
<input type="hidden" id="my_image_base64" name="image_base64" />
<button id="upload_button"> Upload </button>
</form>
<br/>
<canvas id="my_canvas" width="500" />
</body>
</html>
forms.py:
from django import forms
from .models import UploadModel
class StoreImageForm(forms.ModelForm):
class Meta:
model = UploadModel
fields = ['upload_file']
models.py:
from django.db import models
class UploadModel(models.Model):
upload_file = models.ImageField()
在github上查看我的image-minimizer-uploader项目。