Eu encontrei alguns posts diferentes e até mesmo perguntas sobre stackoverflow respondendo a esta pergunta. Estou basicamente implementando a mesma coisa que este post .
Então aqui está o meu problema. Ao fazer upload da foto, também preciso enviar o restante do formulário. Aqui está o meu html:
<form id="uploadImageForm" enctype="multipart/form-data">
<input name="imagefile[]" type="file" id="takePictureField" accept="image/*" onchange="uploadPhotos(\'#{imageUploadUrl}\')" />
<input id="name" value="#{name}" />
... a few more inputs ...
</form>
Anteriormente, eu não precisava redimensionar a imagem, então meu javascript era assim:
window.uploadPhotos = function(url){
var data = new FormData($("form[id*='uploadImageForm']")[0]);
$.ajax({
url: url,
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
... handle error...
}
}
});
};
Tudo funcionou muito bem ... agora que preciso redimensionar as imagens ... como posso substituir a imagem no formulário para que a redimensionada seja postada e não a imagem enviada?
window.uploadPhotos = function(url){
var resizedImage;
// Read in file
var file = event.target.files[0];
// Ensure it's an image
if(file.type.match(/image.*/)) {
console.log('An image has been loaded');
// Load the image
var reader = new FileReader();
reader.onload = function (readerEvent) {
var image = new Image();
image.onload = function (imageEvent) {
// Resize the image
var canvas = document.createElement('canvas'),
max_size = 1200,
width = image.width,
height = image.height;
if (width > height) {
if (width > max_size) {
height *= max_size / width;
width = max_size;
}
} else {
if (height > max_size) {
width *= max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
resizedImage = canvas.toDataURL('image/jpeg');
}
image.src = readerEvent.target.result;
}
reader.readAsDataURL(file);
}
// TODO: Need some logic here to switch out which photo is being posted...
var data = new FormData($("form[id*='uploadImageForm']")[0]);
$.ajax({
url: url,
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
... handle error...
}
}
});
};
Pensei em mover a entrada do arquivo para fora do formulário e ter uma entrada oculta no formulário para o qual defini o valor como o valor da imagem redimensionada ... Mas estou me perguntando se posso simplesmente substituir a imagem que já está no formulário.
fonte
BufferedImage dest = src.getSubimage(rect.x, rect.y, rect.width, rect.height);
Respostas:
Aqui está o que acabei fazendo e funcionou muito bem.
Primeiro, movi a entrada do arquivo para fora do formulário para que não seja enviada:
Então mudei a
uploadPhotos
função para lidar apenas com o redimensionamento:Como você pode ver, estou usando
canvas.toDataURL('image/jpeg');
para alterar a imagem redimensionada em dataUrl e depois chamo a funçãodataURLToBlob(dataUrl);
para transformar dataUrl em um blob que posso anexar ao formulário. Quando o blob é criado, eu aciono um evento personalizado. Esta é a função para criar o blob:Por fim, aqui está meu manipulador de eventos que obtém o blob do evento personalizado, anexa o formulário e o envia.
fonte
width *= max_size / width;
você realmente quis dizerwidth *= max_size / height;
.se houver interesse, fiz uma versão datilografada:
e aqui está o resultado de javascript:
o uso é como:
ou (
async
/await
):fonte
Uncaught (in promise) TypeError: Cannot read property 'type' of undefined
maxSize
está em bytes ou kb?Se alguns de vocês, como eu, encontrarem problemas de orientação, combinei as soluções aqui com uma correção de orientação exif
https://gist.github.com/SagiMedina/f00a57de4e211456225d3114fd10b0d0
fonte