Ответ 1
** ОБНОВЛЕНИЕ ** Февраль 2014 **
Новая и улучшенная версия, доступная как плагин jQuery: https://github.com/CoeJoder/jquery.image.blob
Использование:
$('img').imageBlob().ajax('/upload', {
complete: function(jqXHR, textStatus) { console.log(textStatus); }
});
Требования
- элемент canvas (HTML 5)
- FormData
- XMLHttpRequest.send (: FormData)
- Конструктор Blob
- Uint8Array
- atob(), escape()
Таким образом, требования к браузеру:
- Chrome: 20 +
- Firefox: 13 +
- Internet Explorer: 10 +
- Опера: 12.5 +
- Safari: 6 +
Примечание. Изображения должны быть того же происхождения, что и ваш JavaScript, иначе политика безопасности браузера предотвратит вызовы canvas.toDataURL()
(более подробную информацию см. в этом вопросе SO: Почему canvas.toDataURL() выдает исключение безопасности?). Прокси-сервер может использоваться для обхода этого ограничения посредством вставки заголовка ответа, как описано в ответах на этот пост.
Вот jsfiddle приведенного ниже кода. Он должен выдать сообщение об ошибке, поскольку он не отправляется на реальный URL ('/some/url'). Используйте firebug или аналогичный инструмент для проверки данных запроса и убедитесь, что изображение сериализовано как данные формы (нажмите "Запустить" после загрузки страницы):
Пример разметки
<img id="someImage" src="../img/logo.png"/>
JavaScript
(function() {
// access the raw image data
var img = document.getElementById('someImage');
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
var dataUrl = canvas.toDataURL('image/png');
var blob = dataUriToBlob(dataUrl);
// submit as a multipart form, along with any other data
var form = new FormData();
var xhr = new XMLHttpRequest();
xhr.open('POST', '/some/url', true); // plug-in desired URL
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert('Success: ' + xhr.responseText);
} else {
alert('Error submitting image: ' + xhr.status);
}
}
};
form.append('param1', 'value1');
form.append('param2', 'value2');
form.append('theFile', blob);
xhr.send(form);
function dataUriToBlob(dataURI) {
// serialize the base64/URLEncoded data
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURI.split(',')[1]);
}
else {
byteString = unescape(dataURI.split(',')[1]);
}
// parse the mime type
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// construct a Blob of the image data
var array = [];
for(var i = 0; i < byteString.length; i++) {
array.push(byteString.charCodeAt(i));
}
return new Blob(
[new Uint8Array(array)],
{type: mimeString}
);
}
})();