Загрузка IOS6 и Safari - Файл API + Холст + jQuery Ajax Загрузка и изменение размера файлов асинхронно
IOS6 был выпущен, и я тестировал загрузку фотографий.
Он работает хорошо, но с большими изображениями через 3G он SLOW, как ожидалось.
Благодаря File API и Canvas можно изменять размер изображений с помощью JavaScript. Я надеюсь, что, если я изменил размер изображений до того, как попытаюсь их загрузить, они будут загружаться быстрее - при условии быстрого доступа пользователей. С процессорами смартфонов, которые экспоненциально растут быстрее, чем скорость сети, я считаю, что это решение является победителем.
Николас предложил отличное решение для изменения размера изображения:
Изменение размера изображения перед загрузкой
Тем не менее, у меня сложнее всего реализовать его с помощью jQuery Ajax. Любые советы или помощь приветствуются, так как этот код, вероятно, будет чрезвычайно полезен для разработки мобильных веб-приложений после IOS6.
var fileType = file.type,
reader = new FileReader();
reader.onloadend = function () {
var image = new Image();
image.src = reader.result;
image.onload = function () {
//Detect image size
var maxWidth = 960,
maxHeight = 960,
imageWidth = image.width,
imageHeight = image.height;
if (imageWidth > imageHeight) {
if (imageWidth > maxWidth) {
imageHeight *= maxWidth / imageWidth;
imageWidth = maxWidth;
}
} else {
if (imageHeight > maxHeight) {
imageWidth *= maxHeight / imageHeight;
imageHeight = maxHeight;
}
}
//Create canvas with new image
var canvas = document.createElement('canvas');
canvas.width = imageWidth;
canvas.height = imageHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
// The resized file ready for upload
var finalFile = canvas.toDataURL(fileType);
if (formdata) {
formdata.append("images[]", finalFile);
$.ajax({
url: "upload.php",
type: "POST",
data: formdata,
dataType: 'json',
processData: false,
contentType: false,
success: function (res) {
//successful image upload
}
});
}
}
}
reader.readAsDataURL(file);
Ответы
Ответ 1
Я только что разработал плагин jQuery для изменения размера изображения canvas на стороне клиента .
Он также обрабатывает ориентацию и проблему iOS6 squashed image.
Вы можете попробовать:
http://gokercebeci.com/dev/canvasresize
Использование:
$.canvasResize(file, {
width : 300,
height : 0,
crop : false,
quality : 80,
callback: function(dataURL, width, height){
// your code
}
});
Ответ 2
Я работал с функцией загрузки со второй бета-версии iOS6. Для меня работает следующий код:
Поместите это в начало своей HTML-страницы -
<script>window.onload = function() {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var fileSelect = document.getElementById("fileSelect"),
input = document.getElementById("input");
input.addEventListener("change", handleFiles);
//hides ugly default file input button
fileSelect.addEventListener("click", function (e) {
if (input) {
input.click();
}
e.preventDefault();
}, false);
function handleFiles(e) {
var reader = new FileReader;
reader.onload = function (event) {
var img = new Image();
img.src = reader.result;
img.onload = function () {
var maxWidth = 320,
maxHeight = 350,
imageWidth = img.width,
imageHeight = img.height;
if (imageWidth > imageHeight) {
if (imageWidth > maxWidth) {
imageHeight *= maxWidth / imageWidth;
imageWidth = maxWidth;
}
} else {
if (imageHeight > maxHeight) {
imageWidth *= maxHeight / imageHeight;
imageHeight = maxHeight;
}
}
canvas.width = imageWidth;
canvas.height = imageHeight;
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
// The resized file ready for upload
var finalFile = canvas.toDataURL("image/png");
var postData = 'canvasData=' + finalFile;
var ajax = new XMLHttpRequest();
ajax.open('POST', 'save.php', true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.onreadystatechange = function () {
if (ajax.readyState == 4) {
//just to visually confirm it worked...
window.open(canvas.toDataURL("image/png"), "mywindow");
}
}
ajax.send(postData);
}
}
reader.readAsDataURL(e.target.files[0]);
}
}
</script>
Здесь HTML -
<div style="width:320px;position:absolute;z-index:9;top:387px;">
<button style="width:60px;" id="fileSelect">upload</button>
<input type="file" id="input" name="input" accept="image/*" style="display:none;"></div>
Здесь PHP -
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
// Save file. This example uses a hard coded filename for testing,
// but a real application can specify filename in POST variable
$fp = fopen( 'users/user_photo.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
Единственная проблема, с которой я столкнулся, - это получать изображения с камеры без поворота на 90 градусов.
Надеюсь, что это поможет, сообщите мне, есть ли у вас какие-либо проблемы с кодом (это мой первый пост).
Ответ 3
Учитывая, что мы имеем дело с большими проблемами с изображениями и памятью в мобильном браузере, я хотел посмотреть, можно ли найти легкое решение, позволяющее избежать создания дублирующего холста и выполнять другие операции с изображениями только для обнаружения и изменения размера.
Кажется, что если Mobile Safari вертикально сквозит изображение, которое слишком велико, отношение к тому, насколько оно это делает, остается прежним.
Итак, прямо сейчас, прежде чем я даже сделаю изображение на холсте, я использую очень быстрое эмпирическое правило, в котором я просто проверяю, является ли браузер мобильной iDevice navigator.userAgent.match(/(iPod|iPhone|iPad)/)
... И высота или ширина изображения больше 2000 пикселей, и в этом случае я знаю, что он будет раздавлен.
В этом случае в canvasContext.drawImage()
я определяю высоту изображения на 4 раза выше, чем обычно должен был быть для заданного объектного изменения размера изображения. Основываясь на том, что я видел, Mobile Safari копирует изображение в 4 раза.
Затем я визуализую изображение, и он делает неискаженный первый раз, сбрасывая предварительно растянутое изображение обратно до того, что затем становится нормальной пропорцией X: Y. Без каких-либо дополнительных элементов холста или контекстов или тестовых рендерингов или итераций пикселей, которые упоминаются выше в 100% -ном решении, используется.
Я уверен, что могут быть некоторые случаи кросс, и ограничение размера изображения может быть неточным, но для моего приложения мне нужно решение, которое было FAST.