Сохранение изображения Рафаэля в формате PNG в Internet Explorer

У меня есть хорошая графика, сделанная с помощью Raphaël (библиотека JavaScript) , и я хочу добавить функцию, чтобы сохранить ее как файл PNG.

Это просто в любом браузере, кроме Internet Explorer, потому что в браузерах, отличных от Internet Explorer, я получаю SVG как вывод Raphaël, а затем я могу преобразовать его в холст (используя библиотеку cansvg), а у холста есть метод toDataURL(). Но в Internet Explorer Рафаэль выводит VML. Я не могу использовать подключаемый модуль фрейма Chrome. Почему?

Пользователи моего приложения выбирают Internet Explorer только потому, что он предустановлен в Windows, и у них нет разрешения на установку чего-либо еще. Поэтому они не могут установить этот плагин. Итак, моя вторая идея заключалась в том, чтобы получить строку SVG в Internet Explorer, передать ее в cansvg, чтобы получить холст, а затем использовать flashCanvas.

Я пытался обмануть Рафаэля, чтобы он подумал, что он работает в браузере, отличном от Internet Explorer, и получил SVG в качестве вывода, но мне это не удалось, поскольку Рафаэль использовал некоторые функции JavaScript, которые отсутствуют в Internet Explorer, для создания SVG.

Итак, как мне выполнить эту задачу в Internet Explorer?


person mnowotka    schedule 07.11.2010    source источник
comment
Я не публикую это как ответ, потому что сам не пробовал, но у вас может быть некоторый успех, заставив Рафаэля использовать svg-web, который имеет достойную поддержку SVG DOM API. Тогда методы, которые вы используете в других браузерах, будут такими же. Я думаю, что это может сработать, но вам, возможно, придется немного взломать код raphaeljs. Обратите внимание, что я никогда не читал о том, чтобы кто-то пытался использовать raphaeljs с svg-web, svg-web с canvg или canvg с flashcanvas, поэтому, если вы заставите все это работать, это будет эпический хак, и вам обязательно стоит написать о Это. Удачи :)   -  person jbeard4    schedule 07.11.2010
comment
Как я уже сказал - я заставил его работать во всех браузерах, кроме IE. Могу прикрепить проект aptana, если хотите попробовать.   -  person mnowotka    schedule 07.11.2010
comment
Теперь кое-что об обмане Рафаэля. Это методы, используемые в raphael, которые не поддерживаются в IE: getNumberOfChars (), getExtentOfChar (), createElementNS (), а также были некоторые другие проблемы.   -  person mnowotka    schedule 07.11.2010


Ответы (4)


RaphaelJS не использует холст. Он использует VML в IE, но SVG во всех других браузерах.

Как сказал OP, вы можете взять необработанный SVG (поскольку это целый документ SVG) и загрузить его, он ищет аналогичные функции с VML.

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

Однако, поскольку вам нужен PNG, вам, вероятно, лучше с самого начала выбрать холст, поскольку вам, вероятно, не понадобится векторная сторона графики, если вы затем конвертируете в растровое изображение. Холст оформления заказа и скрипт холста Google IE, чтобы узнать, можно ли его использовать.

Что касается «Поддержка браузером для создания графики все еще довольно ограничена», то это не так. Посмотрите демонстрации RaphaelJS.com, это вполне осуществимое и хорошее решение. Единственная проблема - IE ‹9, который не использует никаких современных технологий, таких как HTML5, CSS3 или SVG.

Все, что поддерживает Canvas или google IEcanvas, также может дать достойные результаты.

person gazhay    schedule 07.12.2010
comment
Excanvas - отстой, Рафаэль намного лучше. При этом я только начал пытаться сохранять рисунки Рафаэля как изображения в IE :). - person Alex Ciminian; 08.01.2011
comment
Я не использовал его, но этот sourceforge.net/projects/vectorconverter теперь существует и может быть модифицирован, чтобы делать то, что вам нужно - person gazhay; 13.04.2012

Рафаэль использует VML в Internet Explorer и SVG во всех других браузерах. Canvas имеет встроенную возможность экспорта как изображения, хотя такая функция не встроена в VML. Вы можете использовать серверный код, чтобы добиться того же для неподдерживаемых браузеров.

Альтернативным решением является использование решений ActiveX для Internet Explorer, которые могут генерировать изображение из VML. Одним из таких решений является компонент ActiveX моментальных снимков HTML.

Как правило, не рекомендуется внедрять решения ActiveX, если это не является абсолютной необходимостью.

person Livingston Samuel    schedule 02.12.2010

Решение PHP и JavaScript (нет необходимости в ImageMagick, Apache Batik Rasterizer или Inkscape!):

Требования

  1. PHP
  2. Flash Player 9+ (для Flashcanvas поправьте меня, если я ошибаюсь)
  3. RaphaelJS
  4. Raphael Export
  5. CanVG
  6. FlashCanvas Free или Pro
  7. Canvas2PNG + save.php (входит в состав FlashCanvas)

Обзор

  1. Начать пустой холст
  2. Нарисуйте VML с Рафаэлем
  3. Используйте Raphael Export для преобразования бумаги из VML в SVG
  4. Инициализировать Flashcanvas на пустом холсте
  5. Отправьте строку SVG из Raphael Export в canvg
  6. После того, как canvg сгенерировал данные SVG на инициированном FlashCanvas холсте, вызовите функцию Flashcanvas Canvas2png.
  7. Бумага сохраняется как PNG! $$$

Авария

  1. Начать пустой холст

    <canvas id="myCanvas"></canvas>
    
  2. Нарисуйте VML с Рафаэлем

    //Basic Example
    var paper = Raphael(10, 50, 320, 200);
    var circle = paper.circle(50, 40, 10);
    circle.attr("fill", "#f00");
    circle.attr("stroke", "#fff");
    
  3. Используйте Raphael Export для преобразования бумаги из VML в SVG.

    var svg = paper.toSVG();
    
  4. Инициализировать Flashcanvas на пустом холсте

    var canvas = document.getElementById('export');
    if (typeof FlashCanvas != "undefined") {
      FlashCanvas.initElement(canvas); //initiate Flashcanvas on our canvas
    }
    
  5. Отправьте строку SVG из Raphael Export в canvg

    canvg(canvas, svg, {
      ignoreMouse: true, //I needed these options so Internet Explorer wouldn't clear the canvas
      ignoreAnimation: true,
      ignoreClear: true,
      renderCallback: function() {
        setTimeout(function() {
          canvas2png(canvas);
        }, 1000);
      }
    });
    
  6. После того, как canvg сгенерировал данные SVG на холсте, вызовите функцию Canvas2png Flashcanvas.

    //This is called within the renderCallback canvg function above:
    renderCallback: function() {
      setTimeout(function() {
        canvas2png(canvas);
      }, 1000);
    }
    
  7. Бумага сохраняется как PNG! $$$

Примечания / выводы

  • НЕ ВКЛЮЧАЙТЕ / ИСПОЛЬЗУЙТЕ EXCANVAS с FLASHCANVAS, эта единственная ошибка, из-за которой я почти неоднократно отказывался от FlashCanvas.
  • Flashcanvas следует включать в <head> как можно раньше, по какой-то причине у меня возникли проблемы при включении flashcanvas.js позже.
  • Canvas2png.js по умолчанию предлагает пользователю сохранить файл .png. В качестве альтернативы вы можете записать .png на свой сервер, отредактировав файл Flashcanvas save.php из:

    readfile('php://input');
    

    Кому:

    //Comment these out so that the download is not forced
    //header('Content-Type: application/octet-stream');
    //header('Content-Disposition: attachment; filename="canvas.png"');
    
    $putdata = fopen("php://input", "r");
    $fp = fopen("path/to/image_name.png", "w");
    while ($data = fread($putdata, 1024)) {
      fwrite($fp, $data);
    }
    fclose($fp);
    fclose($putdata);
    
  • Следуя последнему примечанию: если вы вместо этого решили сохранить изображение на сервере, по умолчанию вы будете перенаправлены на пустой save.php при вызове canvas2png() (save.php не запускается AJAX!), И, таким образом, вы будете потерять текущий сеанс рисования Рафаэля.

Поэтому, если вы хотите вызвать этот метод без потери текущего сеанса Raphael, я решил эту проблему, чтобы сохранить Raphael Paper на одной странице, а страницу <canvas> - на другой.

Общая идея заключается в том, что вы сохраняете свою деятельность по рисованию Рафаэля на главной странице, и когда вы будете готовы экспортировать / сохранить изображение, вы можете открыть новое окно, содержащее пустой холст, и отправить данные SVG на эту новую временную страницу. Оттуда вы можете повторить шаги снова, где мы остановились, за исключением нового окна, а в конце файла save.php, когда изображение было сгенерировано и сохранено, вы можете использовать вызов javascript: self.close(), чтобы закрыть это новое окно.

Нам нужно, чтобы это новое окно появилось, чтобы холст можно было правильно обработать с данными SVG.

  • canvg с Internet Explorer 8 (работал Chrome / Firefox) не смог прочитать изображения, созданные из URL-адреса .php, чтобы исправить это, мне пришлось использовать PHP для сохранения «содержимого URL-адреса php» в качестве временного изображения на сервере и используйте это временное изображение в качестве ссылки для данных SVG, заменив его исходный xlink: href.

  • У canvas2png.js есть запасной вариант, если ваш браузер поддерживает toDataURL, что делает это решение кроссбраузерным.

  • В заключение я подумал, что включу быстрый метод экспорта изображений, если вы используете браузер, поддерживающий toDataURL, из чего я могу сделать вывод, что браузер также поддерживает SVG , и поэтому процесс сохранения изображения намного проще (без хлопот с Flashcanvas):

    1. Initiate an empty canvas
    2. Нарисуйте SVG с Рафаэлем
    3. Экспорт строки SVG с помощью Raphael Export
    4. Используйте canvg для синтаксического анализа данных SVG на пустом холсте
    5. Используйте canvas.toDataURL ()
person projeqht    schedule 21.08.2013

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

Node Canvas только что вышел, и в прошлом я с большим успехом использовал ImageMagick.

person Tim Christensen    schedule 12.11.2010
comment
Что касается поддержки браузером для генерации графики, она все еще довольно ограничена. Посмотрите демонстрации RaphaelJS.com, это вполне осуществимое и хорошее решение. Единственная проблема - IE ‹9, который не использует никаких современных технологий, таких как HTML5, CSS3 или SVG. Это довольно хорошо резюмирует мою точку зрения. - person Alex Ciminian; 08.01.2011
comment
@Alex Его проблема именно в этом. . . Ему нужно поддерживать старые браузеры. Почему не было бы хорошим решением просто сгенерировать изображения на сервере, а затем загрузить их через AJAX? - person Tim Christensen; 10.01.2011