Стандарт 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: *
Вы также можете разрешить только заранее определенный список доменов.
Читайте про кросс-доменный обмен ресурсов
Вот и все. Если у вас есть какие-то другие советы, чтобы разделить, не стесняйтесь комментировать.
Комментарии
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/mozGetAsFile
Сосбственно это в FF только и работает.