Изменение размера изображения перед загрузкой
Мне нужно предоставить пользователю возможность загружать фотографии на свой веб-сайт в формате jpeg. Тем не менее, фотографии очень большие в оригинальном размере, и я хотел бы сделать изменение размера перед настройкой загрузки очень легким для пользователя. Кажется, что мои единственные варианты - это приложение на стороне клиента, которое изменяет размер фотографий перед их загрузкой через веб-службу или клик на стороне клиента в операции загрузки, которая изменяет размеры изображений. Второй вариант очень предварительный, потому что у меня нет библиотеки изменения размера изображения JavaScript, и будет сложно заставить JavaScript запустить мой текущий инструмент изменения размера, ImageMagick.
Я уверен, что это не слишком необычный сценарий, и некоторые предложения или указатели на сайты, которые делают это, будут оценены.
Ответы
Ответ 1
У вас есть несколько вариантов:
Я провел много исследований, которые искали аналогичное решение для того, что вы описали, и там много решений, которые значительно отличаются качеством и гибкостью.
Мое предложение - найти решение, которое будет делать 80% того, что вам нужно, и настроить его в соответствии с вашими потребностями.
Ответ 2
В 2011 году мы можем узнать, как это сделать с файловым API и холстом.
Сейчас это работает только в firefox и chrome.
Вот пример:
var file = YOUR_FILE,
fileType = file.type,
reader = new FileReader();
reader.onloadend = function() {
var image = new Image();
image.src = reader.result;
image.onload = function() {
var maxWidth = 960,
maxHeight = 960,
imageWidth = image.width,
imageHeight = image.height;
if (imageWidth > imageHeight) {
if (imageWidth > maxWidth) {
imageHeight *= maxWidth / imageWidth;
imageWidth = maxWidth;
}
}
else {
if (imageHeight > maxHeight) {
imageWidth *= maxHeight / imageHeight;
imageHeight = maxHeight;
}
}
var canvas = document.createElement('canvas');
canvas.width = imageWidth;
canvas.height = imageHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
// The resized file ready for upload
var finalFile = canvas.toDataURL(fileType);
}
}
reader.readAsDataURL(file);
Ответ 3
Существует несколько технологий Инструмент Plupload, который заявляет, что он может изменять размер перед загрузкой, но я еще не пробовал. Я также нашел подходящий ответ в своем вопросе об использовании javascript-библиотек для обработки двоичных изображений.
Ответ 4
Я думаю, для этого вам нужна Java или ActiveX. Например Тонкая загрузка изображения
Ответ 5
То, что говорят jao и russau, верно. Причина в том, что JavaScript не имеет доступа к локальной файловой системе из-за соображений безопасности. Если JavaScript может "видеть" ваши файлы изображений, он может видеть любой файл, и это опасно.
Для этого вам нужен элемент управления на уровне приложения, а это значит, что Flash, Java или Active-X.
Ответ 6
К сожалению, вы не сможете изменить размер изображений в Javascript. Это возможно в Silverlight 2 tho.
Если вы хотите купить что-то уже сделанное: Aurigma Image Uploader довольно впечатляет - $USD250 для версий ActiveX и Java. Там некоторые демонстрации на сайте, я уверен, что facebook использует один и тот же элемент управления.
Ответ 7
Чистое решение для JavaScript. Мой код изменяет размер JPEG с помощью билинейной интерполяции, и он не теряет exif.
https://github.com/hMatoba/JavaScript-MinifyJpegAsync
function post(data) {
var req = new XMLHttpRequest();
req.open("POST", "/jpeg", false);
req.setRequestHeader('Content-Type', 'image/jpeg');
req.send(data.buffer);
}
function handleFileSelect(evt) {
var files = evt.target.files;
for (var i = 0, f; f = files[i]; i++){
var reader = new FileReader();
reader.onloadend = function(e){
MinifyJpegAsync.minify(e.target.result, 1280, post);
};
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
Ответ 8
Вы можете изменить размер изображения на стороне клиента, прежде чем загружать его, используя среду обработки изображений.
Ниже я использовал MarvinJ для создания исполняемого кода на основе примера на следующей странице: "Обработка изображений на стороне клиента перед его загрузкой на сервер"
В основном я использую метод Marvin.scale(...), чтобы изменить размер изображения. Затем я загружаю изображение в виде блоба (используя метод image.toBlob()). Сервер отвечает обратно, предоставляя URL полученного изображения.
/***********************************************
* GLOBAL VARS
**********************************************/
var image = new MarvinImage();
/***********************************************
* FILE CHOOSER AND UPLOAD
**********************************************/
$('#fileUpload').change(function (event) {
form = new FormData();
form.append('name', event.target.files[0].name);
reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onload = function(){
image.load(reader.result, imageLoaded);
};
});
function resizeAndSendToServer(){
$("#divServerResponse").html("uploading...");
$.ajax({
method: 'POST',
url: 'https://www.marvinj.org/backoffice/imageUpload.php',
data: form,
enctype: 'multipart/form-data',
contentType: false,
processData: false,
success: function (resp) {
$("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
},
error: function (data) {
console.log("error:"+error);
console.log(data);
},
});
};
/***********************************************
* IMAGE MANIPULATION
**********************************************/
function imageLoaded(){
Marvin.scale(image.clone(), image, 120);
form.append("blob", image.toBlob());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
<input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>
Ответ 9
Вот некоторые модификации, чтобы подать tenorflow.js (так быстро с этим !!) с измененным и обрезанным изображением (256x256px), плюс показ оригинального изображения под обрезанным изображением, чтобы увидеть, что обрезано.
$("#image-selector").change(function(){
var file = $("#image-selector").prop('files')[0];
var maxSize = 256; // well now its minsize
var reader = new FileReader();
var image = new Image();
var canvas = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
var dataURItoBlob = function (dataURI) {
var bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?
atob(dataURI.split(',')[1]) :
unescape(dataURI.split(',')[1]);
var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
var max = bytes.length;
var ia = new Uint8Array(max);
for (var i = 0; i < max; i++)
ia[i] = bytes.charCodeAt(i);
return new Blob([ia], { type: mime });
};
var resize = function () {
var width = image.width;
var height = image.height;
if (width > height) {
if (width > maxSize) {
width *= maxSize / height;
height = maxSize;
}
} else {
if (height > maxSize) {
height *= maxSize / width;
width = maxSize;
}
}
if (width==height) { width = 256; height = 256; }
var posiw = 0;
var posih = 0;
if (width > height) {posiw = (width-height)/2; }
if (height > width) {posih = ((height - width) / 2);}
canvas.width = 256;
canvas.height = 256;
canvas2.width = width;
canvas2.height = height;
console.log('iw:'+image.width+' ih:'+image.height+' w:'+width+' h:'+height+' posiw:'+posiw+' posih:'+posih);
canvas.getContext('2d').drawImage(image, (-1)*posiw, (-1)*posih, width, height);
canvas2.getContext('2d').drawImage(image, 0, 0, width, height);
var dataUrl = canvas.toDataURL('image/jpeg');
var dataUrl2 = canvas2.toDataURL('image/jpeg');
if ($("#selected-image").attr("src")) {
$("#imgspeicher").append('<div style="width:100%; border-radius: 5px; background-color: #eee; margin-top:10px;"><div style="position: relative; margin:10px auto;"><img id="selected-image6" src="'+$("#selected-image").attr("src")+'" style="margin: '+document.getElementById('selected-image').style.margin+';position: absolute; z-index: 999;" width="" height=""><img id="selected-image2" src="'+$("#selected-image2").attr("src")+'" style="margin: 10px; opacity: 0.4;"></div><div class="row" style="margin:10px auto; text-align: left;"> <ol>'+$("#prediction-list").html()+'</ol> </div></div>');
}
$("#selected-image").attr("src",dataUrl);
$("#selected-image").width(256);
$("#selected-image").height(256);
$("#selected-image").css('margin-top',posih+10+'px');
$("#selected-image").css('margin-left',posiw+10+'px');
$("#selected-image2").attr("src",dataUrl2);
$("#prediction-list").empty();
console.log("Image was loaded, resized and cropped");
return dataURItoBlob(dataUrl);
};
return new Promise(function (ok, no) {
reader.onload = function (readerEvent) {
image.onload = function () { return ok(resize()); };
image.src = readerEvent.target.result;
};
let file = $("#image-selector").prop('files')[0];
reader.readAsDataURL(file);});});
HTML реализация:
<input id ="image-selector" class="form-control border-0" type="file">
<div style="position: relative; margin:10px auto; width:100%;" id="imgnow">
<img id="selected-image" src="" style="margin: 10px; position: absolute; z-index: 999;">
<img id="selected-image2" src="" style="margin: 10px; opacity: 0.4;">
</div>
Также не размер до максимальной ширины/высоты, но до минимума. Мы получаем квадратное изображение размером 256x256 пикселей.