Стандарт HTML5 привносит новое, удивительное API. Если вы соедините это API с элементом <canvas> то вы можете получить супер современный загрузчик изображений. Эта статья расскажет, как это сделать. Все эти советы хорошо работают в Firefox 4. Также будут описываться некоторые альтернативные способы, чтобы убедиться, что они работают на Webkit-браузерах. Большинство из этих API, не работают в IE, но это довольно простой способ в использовании, и вполне годиться в качестве запасного варианта. 

Было бы неплохо, если бы кто-то отписал в комментариях, как он использует ту или иную технологию уже сейчас в своих проектах.

 

Получить изображение

Drag and drop

Чтобы загрузить файл на сервер, Вам понадобится элемент <input type=”file”>. Но вы также должны позволить пользователю перетаскивать изображения с рабочего стола прямо на веб-страницу Вашего сайта. 

Множественный выбор файлов для загрузки

Чтобы позволить пользователю выбрать за один раз несколько файлов надо вставить в элемент file атрибут multiple

<input type="file" multiple>

Предварительная обработка файлов 

Используем File API

(Детали работы с File API смотрите здесь)

После того как вы выбрали файлы в элемент file, датапикером или при помощи drag&drop у Вас есть список файлов готовых к использованию.

//из type="file"
var filesToUpload = input.files;
//либо при помощи Drag-and-Drop
function onDrop(e) {
  filesToUpload = e.dataTransfer.files;
}

Убедитесь, что эти файлыявляются изображениями:

if (!file.type.match(/image.*/)) {
  // этот файл не изображение
};

Показать миниатюрку/превьюшку

Есть два варианта. Вы можете использовать FileReader (из File API), или использовать новый метод createObjectURL () . 

createObjectURL()

var img = document.createElement("img");
img.src = window.URL.createObjectURL(file);

FileReader

var img = document.createElement("img");
var reader = new FileReader();  
reader.onload = function(e) {img.src = e.target.result}
reader.readAsDataURL(file);

Используем Canvas

Вы можете нарисовать <img> файл на элементе <canvas> для последующей его обработки

var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);

Изменение размера изображения 

Люди привыкли загружать изображения прямо из своей камеры. Это дает высокое разрешение и чрезвычайно тяжелые (несколько мегабайт) файлы. В зависимости от использования, вы можете изменить размер таких изображений. Фокус в том, чтобы просто иметь небольшой canvas(800 × 600, например) и нарисовать это изображение в этот canvas. Конечно, вам придется изменить размеры canvas'а, чтобы сохранить отношения сторон изображения.

var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
 
if (width > height) {
  if (width > MAX_WIDTH) {
    height *= MAX_WIDTH / width;
    width = MAX_WIDTH;
  }
} else {
  if (height > MAX_HEIGHT) {
    width *= MAX_HEIGHT / height;
    height = MAX_HEIGHT;
  }
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);

Редактирование изображения

Теперь у вас есть изображение в canvas. Теперь Ваши возможности безграничны. Допустим, вы хотите применить фильтр сепия: 

var imgData = ctx.createImageData(width, height);
var data = imgData.data;
var pixels = ctx.getImageData(0, 0, width, height);
for (var i = 0, ii = pixels.data.length; i < ii; i += 4) {
    var r = pixels.data[i + 0];
    var g =pixels.data[i + 1];
    var b = this.pixels.data[i + 2];
    data[i + 0] = (r * .393) + (g *.769) + (b * .189);
    data[i + 1] = (r * .349) + (g *.686) + (b * .168)
    data[i + 2] = (r * .272) + (g *.534) + (b * .131)
    data[i + 3] = 255;
}
ctx.putImageData(imgData, 0, 0);

Загрузить с XMLHttpRequest 

Теперь, когда вы загрузили изображения на клиента, в конечном итоге Вы хотите отправить их на сервер.

 Как отправить canvas

Опять же, у Вас есть два варианта. Вы можете конвертировать canvas очень длинный URL или (в Firefox) создать файл из canvas. 

canvas.toDataURL()

var dataurl = canvas.toDataURL("image/png");


Создайте файл из canvas 

var file = canvas.mozGetAsFile("foo.png");

Неделимая загрузка

Разрешить пользователю загрузить только один файл или все файлы, в то же время.

Показать ход загрузки 

Используйте событие загрузки для создания индикатора:

xhr.upload.addEventListener("progress", function(e) {
  if (e.lengthComputable) {
    var percentage = Math.round((e.loaded * 100) / e.total);
    // do something
}, false);

Используйте FormData

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

В этом случае вы должны создать multipart/form-data запрос с помощью объекта FormData 

var fd = new FormData();
fd.append("name", "paul");
fd.append("image", canvas.mozGetAsFile("foo.png"));
fd.append("key", "××××××××××××");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://your.api.com/upload.json");
xhr.send(fd);


Откройте Ваше API сайта

Может быть, вы хотите, чтобы другие сайты, использовали Ваш сайт как сервис.\

Разрешите cross-добменные запросы 

По умолчанию, Ваше API доступно только из запроса созданного только из вашего собственного домена. Если вы хотите,  позволить людям использовать свой API, разрешите кросс-XHR в заголовке HTTP:

Access-Control-Allow-Origin: *

Вы также можете разрешить только заранее определенный список доменов. 

Читайте про кросс-доменный обмен ресурсов

Вот и все. Если у вас есть какие-то другие советы, чтобы разделить, не стесняйтесь комментировать. 

Источник

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

alexpts
# alexpts 07.05.2011 01:47
Все полностью сделать пробовали сами? Или просто статью с сайта мозилы перевели?
Leroy
# Leroy 09.05.2011 22:37
По работе с чем сталкиваюсь то и делал, нашел в статье интересующие вещи и сделал вывод что статья полезна, потому и перевел. То, что это должно работать в статье не написано, это пока лишь стандарт, но кое что уже можно пощупать тот же multiple или canvas
Юрий1234
# Юрий1234 01.12.2017 02:01
Если бы Вы практически попробовали то, что написали, то в Опере выдает ошибку на Вашем fd.append("image", canvas.mozGetAsFile("foo.png")); На этом коде fd.append("image", canvas.getAsFile("foo.png")); тоже ошибка и так весь этот доблестный интернет. Выложите пожалуйста рабочий код от создания канваса и отправки его на Javascripte до рнр загрузки. А то вроде и что-то стараетесь, а толку- не работает Ваш код. Вон и еще один страдалец Вам тоже самое пишет. Юрий
adel
# adel 01.12.2017 13:39
Это префиксный варинат который работает только в mozilla FF
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/mozGetAsFile
Сосбственно это в FF только и работает.
adel
# adel 01.12.2017 13:39
А какая у вас задача?