Загрузить несколько изображений холста через цикл JavaScript

Я пытаюсь создать скрипт загрузки, который изменяет размер клиентской части изображения перед saveimage.php обрабатывает их. Причина этого заключается в том, что они будут загружены на внешнем месте, где может быть очень медленный интернет.

Я был в состоянии найти части кода здесь, которые помогли мне собрать его вместе. Я только новичок, так что это, вероятно, очень грязно!

В настоящее время он проверяет каждый раз, когда файлы вводятся в поле file_input. Затем он просматривает количество файлов и просматривает их, пока каждый файл не будет помещен на холст и загружен, пока он там.

Однако проблема заключается в следующем: когда я не добавляю предупреждение для каждого файла, цикл идет слишком быстро и обрабатывает, например, только 1 или 2 из 10 изображений. Поскольку скрипт загрузки будет работать быстрее, чем холст, можно будет обновить его новым изображением.

Это моя текущая страница, упрощенная до сути:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
</head>
<body>

<form>
<input id="file_input" type='file' multiple />
</form>

<div id="preview">
<canvas id="canvas"></canvas>
</div>

<script>

var input = document.getElementById('file_input');
input.addEventListener('change', handleFiles);

function handleFiles(e) {

var files = input.files;
alert(files.length +" files are being uploaded!"); // display amount of files for testing purpose

for (var i = 0; i < files.length; ++i) {

alert("Upload file number: "+i); // display file # for testing purpose, when this is removed the script will go too fast

var MAX_HEIGHT = 1000;
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image;

img.onload = function(){
if(img.height > MAX_HEIGHT) {
img.width *= MAX_HEIGHT / img.height;
img.height = MAX_HEIGHT;
}
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
preview.style.width = img.width + "px";
preview.style.height = img.height + "px";
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);

// the canvas should contain an image now and this will send it through saveimage.php
var myDrawing = document.getElementById("canvas");
var drawingString = myDrawing.toDataURL("image/jpeg", 0.5);
var postData = "canvasData="+drawingString;
var ajax = new XMLHttpRequest();
ajax.open("POST",'saveimage.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4);
}
ajax.send(postData);
};

img.src = URL.createObjectURL(e.target.files[i]);
}
}

</script>

</body>
</html>

А это мой saveimage.php который работает хорошо, но только для полного обзора:

<?php

if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
$rawImage=$GLOBALS['HTTP_RAW_POST_DATA'];
$removeHeaders=substr($rawImage, strpos($rawImage, ",")+1);
$decode=base64_decode($removeHeaders);

// check if the file already exists and keep adding +1 intil it's unique
$i = 1;
while(file_exists('uploads/image'.$i.'.jpg')) {
$i++;
}

$fopen = fopen( 'uploads/image'.$i.'.jpg', 'wb' );
fwrite( $fopen, $decode);
fclose( $fopen );

}

?>

Немного дополнительной информации:

  • Я добавил холст, потому что, насколько я понимаю, это
    Единственный способ изменить размер изображения на стороне клиента. В финальном сценарии это будет
    установить скрытый.
  • Если холст может быть пропущен и данные отправлены saveimage.php
    Я думаю, что сразу же это решит проблему.
  • Как я уже сказал, я не очень опытен с Javascript, поэтому, если есть
    гораздо более простой способ достижения этой цели. Пожалуйста, дайте мне знать!

Заранее спасибо!

0

Решение

JavaScript загружает изображение асинхронно. Это означает, что как только ему будет присвоено новое изображение .src, оно начнет загружать изображение, но одновременно продолжит обработку javascript после .src, пока изображение загружается.

Вы используете ту же переменную изображения (var imgЗапусти свой цикл. Поэтому каждый раз в цикле вы перезаписываете предыдущий img до полной загрузки предыдущего изображения.

Вот загрузчик изображений, который полностью загружает все изображения и затем вызывает функцию start (), где вы можете выполнять обработку:

// image loader

// put the paths to your images in imageURLs[]
var imageURLs=[];
imageURLs.push("myImage1.png");
imageURLs.push("myImage2.png");
// etc, etc.

// the loaded images will be placed in imgs[]
var imgs=[];

var imagesOK=0;
loadAllImages(start);

function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}

function start(){

// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]

}
1

Другие решения

В обратном вызове onload используйте this ключевое слово (вместо img) для текущего изображения, img may / будет перезаписано в цикле for до срабатывания обратного вызова.
img.height --> this.height так далее
Также есть причина, по которой вы используете пользовательский тип контента вместо application/x-www-form-urlencoded ?
С данными, закодированными в форме URL, работать намного проще.

0

Я боролся с той же проблемой в течение некоторого времени, но я, наконец,
соединили другое решение, используя биты кода от других, которые обратились к этой проблеме,
и это работает. Это может быть не идеально, и я буду рад любым предложениям по улучшению.
Концепция заключается в том, что у вас есть два Javascript
Функции, которые идентичны, называются Resize0 и Resize1, и они вызывают друг друга
пока все фотографии не будут изменены, то функция, которая изменяет размер
Последнее изображение Отправляет форму. Две функции передают параметры между
друг с другом, чтобы один из них знал, когда отправить форму.
Два из этих параметров, Number_Of_Images и текущий Image_Number.
Вы также можете загрузить рабочую страницу примера с
http://www.wantitconsulting.co.nz/ExampleResizeUpload.zip .
Вам нужно будет создать папку в базовом каталоге вашего тестового веб-сайта.
для изображений, чтобы войти в. Следующее имя — TestResizeUpload. Сервер
сторона использует php.

0

У меня была такая же проблема, но мне удалось справиться с этим, сначала отобразив все изображения в скрытом теге «img», взяв в качестве ссылки этот пост «HTML5 для отображения загруженного изображения, пока не будет загружено следующее?«и после этого я запускаю функцию с дополнительной кнопкой, которая использует недавно созданные изображения, и рисую их все на отдельном холсте, который также был создан в то же время, что и изображения, при загрузке которых код будет выглядеть так

HTML:

<form>
<input type="file" id="files" name="files[]" multiple />
<button type="button" id="run">Run</button>
</form>

<div id="preview">
<output id="list"></output><br>
<output id="list2"></output><br>
<div id="status"></div>
</div>

Сценарий:

document.getElementById('files').addEventListener('change', handleFileSelect,false);
document.getElementById('run').addEventListener('click', read);

function handleFileSelect(evt) {
var files = evt.target.files; // FileList object

// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {

// Only process image files.
if (!f.type.match('image.*')) {
continue;
}

var reader = new FileReader();

// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" name="forms" src="', e.target.result, '" title="', escape(theFile.name), '"/ hidden>'].join('');
document.getElementById('list').insertBefore(span, null);
var span = document.createElement('span');
span.innerHTML = ['<canvas></canvas>'].join('');
document.getElementById('list2').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}

function read() {
imgs = document.getElementsByName('forms');
canvas = document.getElementsByTagName("canvas");
for (var i = 0; i < imgs.length; ++i) {
ctx[i] = canvas[i].getContext("2d");
ctx[i].clearRect(0, 0, canvas[i].width, canvas[i].height);
preview.style.width = imgs[i].width + "px";
preview.style.height = imgs[i].height + "px";
canvas[i].width = imgs[i].width;
canvas[i].height = imgs[i].height;
ctx[i].drawImage(imgs[i], 0, 0, imgs[i].width, imgs[i].height);
// do all you need with each new canvas canvas
}
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector