업로드하기 전에 HTML5를 사용하여 이미지 크기 조정
이 질문에 답하는 stackoverflow에 대한 몇 가지 다른 게시물과 질문을 발견했습니다. 기본적 으로이 게시물 과 동일한 것을 구현하고 있습니다.
그래서 여기에 내 문제가 있습니다. 사진을 업로드 할 때 나머지 양식도 제출해야합니다. 내 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>
이전에는 이미지 크기를 조정할 필요가 없었으므로 내 자바 스크립트는 다음과 같이 보입니다.
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...
}
}
});
};
이 모든 것이 훌륭하게 작동했습니다 ... 이제 이미지 크기를 조정해야합니다. 업로드 된 이미지가 아닌 크기가 조정 된 이미지가 게시되도록 양식의 이미지를 어떻게 바꿀 수 있습니까?
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...
}
}
});
};
파일 입력을 양식 밖으로 옮기고 크기를 조정 한 이미지의 값으로 값을 설정 한 양식에 숨겨진 입력을 갖는 것에 대해 생각했습니다 ...하지만 이미지를 대체 할 수 있는지 궁금합니다. 이미 양식에 있습니다.
여기에 내가 한 일이 있으며 훌륭하게 작동했습니다.
먼저 제출되지 않도록 파일 입력을 양식 외부로 이동했습니다.
<input name="imagefile[]" type="file" id="takePictureField" accept="image/*" onchange="uploadPhotos(\'#{imageUploadUrl}\')" />
<form id="uploadImageForm" enctype="multipart/form-data">
<input id="name" value="#{name}" />
... a few more inputs ...
</form>
그런 다음 uploadPhotos크기 조정 만 처리 하도록 함수를 변경했습니다 .
window.uploadPhotos = function(url){
// 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 = 544,// TODO : pull max size from a site config
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);
var dataUrl = canvas.toDataURL('image/jpeg');
var resizedImage = dataURLToBlob(dataUrl);
$.event.trigger({
type: "imageResized",
blob: resizedImage,
url: dataUrl
});
}
image.src = readerEvent.target.result;
}
reader.readAsDataURL(file);
}
};
보시다시피 canvas.toDataURL('image/jpeg');크기가 조정 된 이미지를 dataUrl adn으로 변경하는 데 사용 하고 있으며 함수 dataURLToBlob(dataUrl);를 호출 하여 dataUrl을 blob으로 변환 한 다음 양식에 추가 할 수 있습니다. Blob이 생성되면 사용자 지정 이벤트를 트리거합니다. 다음은 Blob을 만드는 함수입니다.
/* Utility function to convert a canvas to a BLOB */
var dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = parts[1];
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType});
}
/* End Utility function to convert a canvas to a BLOB */
마지막으로 사용자 지정 이벤트에서 blob을 가져 와서 양식을 추가 한 다음 제출하는 이벤트 처리기입니다.
/* Handle image resized events */
$(document).on("imageResized", function (event) {
var data = new FormData($("form[id*='uploadImageForm']")[0]);
if (event.blob && event.url) {
data.append('image_data', event.blob);
$.ajax({
url: event.url,
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
//handle errors...
}
});
}
});
관심이 있다면 typescript 버전을 만들었습니다.
interface IResizeImageOptions {
maxSize: number;
file: File;
}
const resizeImage = (settings: IResizeImageOptions) => {
const file = settings.file;
const maxSize = settings.maxSize;
const reader = new FileReader();
const image = new Image();
const canvas = document.createElement('canvas');
const dataURItoBlob = (dataURI: string) => {
const bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?
atob(dataURI.split(',')[1]) :
unescape(dataURI.split(',')[1]);
const mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
const max = bytes.length;
const ia = new Uint8Array(max);
for (var i = 0; i < max; i++) ia[i] = bytes.charCodeAt(i);
return new Blob([ia], {type:mime});
};
const resize = () => {
let width = image.width;
let height = image.height;
if (width > height) {
if (width > maxSize) {
height *= maxSize / width;
width = maxSize;
}
} else {
if (height > maxSize) {
width *= maxSize / height;
height = maxSize;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
let dataUrl = canvas.toDataURL('image/jpeg');
return dataURItoBlob(dataUrl);
};
return new Promise((ok, no) => {
if (!file.type.match(/image.*/)) {
no(new Error("Not an image"));
return;
}
reader.onload = (readerEvent: any) => {
image.onload = () => ok(resize());
image.src = readerEvent.target.result;
};
reader.readAsDataURL(file);
})
};
다음은 자바 스크립트 결과입니다.
var resizeImage = function (settings) {
var file = settings.file;
var maxSize = settings.maxSize;
var reader = new FileReader();
var image = new Image();
var canvas = 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) {
height *= maxSize / width;
width = maxSize;
}
} else {
if (height > maxSize) {
width *= maxSize / height;
height = maxSize;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
var dataUrl = canvas.toDataURL('image/jpeg');
return dataURItoBlob(dataUrl);
};
return new Promise(function (ok, no) {
if (!file.type.match(/image.*/)) {
no(new Error("Not an image"));
return;
}
reader.onload = function (readerEvent) {
image.onload = function () { return ok(resize()); };
image.src = readerEvent.target.result;
};
reader.readAsDataURL(file);
});
};
사용법은 다음과 같습니다.
resizeImage({
file: $image.files[0],
maxSize: 500
}).then(function (resizedImage) {
console.log("upload resized image")
}).catch(function (err) {
console.error(err);
});
또는 ( async/ await) :
const config = {
file: $image.files[0],
maxSize: 500
};
const resizedImage = await resizeImage(config)
console.log("upload resized image")
If some of you, like me, encounter orientation problems I have combined the solutions here with a exif orientation fix
https://gist.github.com/SagiMedina/f00a57de4e211456225d3114fd10b0d0
참고URL : https://stackoverflow.com/questions/23945494/use-html5-to-resize-an-image-before-upload
'Programing' 카테고리의 다른 글
| Visual Studio-솔루션을 중단하지 않고 프로젝트의 폴더 이름과 솔루션 이름을 변경하는 방법 (0) | 2020.10.05 |
|---|---|
| JavaScript를 사용하여 모든 텍스트를 선택 해제하는 기능이 있습니까? (0) | 2020.10.05 |
| jUnit 4.x의 Before and After Suite 실행 후크 (0) | 2020.10.05 |
| 컴파일 타임에 응용 프로그램 폴더로 파일 복사 (0) | 2020.10.05 |
| LaTeX에서 두 그림을 같은 페이지에 유지하는 방법은 무엇입니까? (0) | 2020.10.05 |