2015-02-18 2 views
1

Я загрузил файл изображения размером 47 МБ с сервера и отобразил его на холсте для редактирования.Сохранение большого холста в качестве URI данных после редактирования

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

В настоящее время я использую этот код, чтобы получить данные URI:

drawingCanvas.toDataURL("image/png"); 

Это несколько быстрее, чтобы получить данные JPEG URI, но мне нужно файл только формат PNG. Есть ли способ сделать это быстрее?

+0

Попробуйте использовать метод HTMLCanvasElement.prototype.toBlob, но он работает только для FF и IE10 + (msToBlob). Также вы можете нарисовать часть изображения в холсте, прочитать эту часть с помощью toDataURL/toBlob и нарисовать новую, прочитать ее и сделать ее в цикле :) – Pinal

+0

На ум приходят несколько возможностей: (1) Вы могли бы использовать советы Пинала и разбить ваше изображение на несколько более мелких холстов и сохранить те небольшие холсты к изображениям. (2) Вы также можете сериализовать только изменения, а не пытаться сохранить изображение и редактировать. (3) Возможно, ваш проект лучше всего сделать как приложение для настольных компьютеров и ноутбуков вместо приложения для браузера (4) Предложите свое приложение только в Chrome или Firefox, где пользователи теперь могут щелкнуть правой кнопкой мыши - сохранить холст в качестве изображения и отправить пользователю это изображение для вас в качестве загрузки файла на ваш сервер. – markE

+0

Спасибо, что вы используете «HTMLCanvasElement.prototype.toBlob», чтобы получить что-то быстрее, без проблем я добавил compatablility для него – user3458948

ответ

0

Этот файл слишком велик для обработки через URI данных. Существуют ограничения в разных браузерах, см. Data protocol URL size limitations

Вы можете попытаться опубликовать кодированные данные base64 на свой сервер, декодировать и получить обычное изображение. Упрощенное решение представлено на PHP, но среда не имеет значения.

list($type, $data) = explode(';', $_POST['data']); 
list(, $base64) = explode(',', $data); 
unset($data); 
$decoded = base64_decode($base64, true); 
unset($base64); 

if (false !== $decoded) { 
    header('Content-type: ' . $type); 
    header('Content-Disposition: attachment; filename="file.png"'); 
    header('Cache-Control: max-age=0'); 
    echo $decoded; 
} else { 
    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); 
} 
+0

Да, можете ли вы сказать мне, есть ли способ получить изображение с холста вместо использования холста.toDataURL ("изображение/PNG"); – user3458948

+0

Я добавил свой ответ выше –

+0

Спасибо, мне нужно получить данные с холста. Он содержит большие данные изображения, чтобы получить, что URL-адрес данных с холста становится медленным. – user3458948

0

Нет, к сожалению. PNG-кодирование - относительный медленный процесс сам по себе (вы можете видеть это с большими изображениями, сохраненными в таких приложениях, как Photoshop).

Единственный эффективный способ ускорить работу - уменьшить размер растрового изображения canvas, который вы хотите кодировать - браузер не является оптимальным инструментом для обработки больших данных, таких как большие файлы изображений (размерные размеры), и они никогда не хотел делать подобные вещи.

Разбивка нарезанных фрагментов может помочь вам разблокировать пользовательский интерфейс. Но поскольку вы не можете кодировать их параллельно, и есть накладные расходы на создание кодированных данных Base-64, вам нужно будет использовать async setTimeout, чтобы дать браузеру некоторое время проанализировать очередь событий между каждым срезом и, конечно же, вам нужно было бы скомпоновать их в какой-то момент, где-то, так что это сделало бы его медленнее, более подверженным ошибкам и более сложным все-в-одном (сложный не нужен плохо, хотя в таких случаях). Вероятно, это ваш лучший выбор, хотя если уменьшить размер растрового изображения, это не вариант. И, как указывает Макс, существуют ограничения по размеру для данных-урис.

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

Общие веб-работники могут теоретически делать кодирование параллельно, но, скорее всего, будут намного медленнее, чем позволить браузеру делать это в скомпилированном коде. Вам также нужно будет предоставить код для кодирования ... И, как и во многих новых вещах, у него пока нет полной или полной поддержки.

+0

Да, вы правы, iam googling для решения со вчерашнего дня я не получил лучшего решения до сих пор – user3458948

Смежные вопросы