php imagick svg to png
Convert SVG image to PNG with PHP
I’m working on a web project that involves a dynamically generated map of the US coloring different states based on a set of data.
This SVG file gives me a good blank map of the US and is very easy to change the color of each state. The difficulty is that IE browsers don’t support SVG so in order for me to use the handy syntax the svg offers, I’ll need to convert it to a JPG.
Ideally, I’d like to do this with only the GD2 library but could also use ImageMagick. I have absolutely no clue how to do this.
Any solution that would allow me to dynamically change the colors of states on a map of the US will be considered. The key is that it is easy to change the colors on the fly and that it is cross browser. PHP/Apache solutions only, please.
8 Answers 8
That’s funny you asked this, I just did this recently for my work’s site and I was thinking I should write a tutorial. Here is how to do it with PHP/Imagick, which uses ImageMagick:
the steps regex color replacement may vary depending on the svg path xml and how you id & color values are stored. If you don’t want to store a file on the server, you can output the image as base 64 like
(before you use clear/destroy) but ie has issues with PNG as base64 so you’d probably have to output base64 as jpeg
you can see an example here I did for a former employer’s sales territory map:
Finish:
Since writing the above, I’ve come up with 2 improved techniques:
and then you can do a single text replace to inject your css rules into the svg before proceeding with the imagick jpeg/png creation. If the colors don’t change, check to make sure you don’t have any inline fill styles in your path tags overriding the css.
2) If you don’t have to actually create a jpeg/png image file (and don’t need to support outdated browsers), you can manipulate the svg directly with jQuery. You can’t access the svg paths when embedding the svg using img or object tags, so you’ll have to directly include the svg xml in your webpage html like:
Конвертация SVG в PNG: а воз и ныне там, но есть варианты
Рассказывает Александр Топорков, веб-разработчик Email Soldiers
Графический формат SVG (Scalable Vector Graphics) — самый распространённый сегодня формат векторной графики, которая выгодно отличается от растровой, в первую очередь, возможностью масштабирования и преобразования изображений. Но иногда требуется конвертация SVG в PNG (Portable Network Graphics) — формат растровой графики.
Современные требования к изображениям высоки. Они должны выглядеть симпатично везде: от телефона до огромного экрана. Без векторной графики не обойтись: логотипы, схемы, иллюстрации лучше делать именно векторными — это становится очевидным, если сравнить разные форматы одного и того же изображения при масштабировании:
Зачем преобразовывать SVG в PNG
Формат SVG по меркам информационных технологий уже давний. С выхода первой версии в 2001 году до актуальной на сегодняшний день версии от 16 августа 2011 прошло целых десять лет. SVG поддерживают все браузеры, и, казалось бы, весь интернет уже должен перейти на векторную графику. Но до сих пор существует масса ограничений на использование SVG.
Так что если у вас на сайте много векторной графики, пока рано отказываться от растровых картинок — придётся использовать и векторную графику, и её растровый аналог. Растровые изображения нельзя автоматически сконвертировать в векторные, поэтому конвертируем векторные.
Отображение векторных изображений на растровом экране — это, по сути, уже конвертация. Задача, казалось бы, тривиальная, но у меня, например, возникли неожиданные трудности.
У одного из наших клиентов (строительной компании) иллюстрации к продаваемой недвижимости были в SVG-формате: разнообразные чертежи и планы. И мы должны были сконвертировать векторные изображения SVG в растровые PNG — для больших YML-фидов, чтобы импортировать эти существенные объёмы данных в Mindbox и там создать товарные рекомендации, которые в дальнейшем вставлять в рассылки.
Задача конвертации SVG в PNG довольно типовая — в сети масса статей на эту тему с примерами кода. Неразумно использовать свою реализацию алгоритма растеризации SVG: сложно, долго и — словно изобретать велосипед. Нужно использовать готовые библиотеки.
Первая попытка: PHP с библиотекой ImageMagick
Начал я с ImageMagick — программы для работы с графикой, своего рода программным Photoshop. И её возможностями можно пользоваться изнутри программ на PHP. Надо лишь подключить PHP-библиотеку Imagick, то есть специальную комплектацию для PHP.
С этой библиотекой код конвертации SVG в PNG кажется элементарным:
$imagick = new Imagick();
$fp = fopen(‘image.svg’, ’rb’);
$imagick->setImageFormat(«png8«); //png8 — это png c 8-битной палитрой
Но он не заработал. Оказывается, поддержка SVG в ImageMagick не включена по умолчанию, и необходимо подключить ещё одну библиотеку libmagickcore-6.q16-3-extra. К счастью, на нашем хостинге операционная система Debian Linux, которая позволяет устанавливать любые программы и библиотеки без ограничений.
sudo apt-get install libmagickcore-6.q16-3-extra
Появилась поддержка SVG. Тестовый код заработал. Но когда я таким способом стал массово конвертировать файлы, программа споткнулась на одном подозрительном файле: она просто остановилась, и ничего не происходило. Ошибка не показывалась, скрипт продолжал «висеть».
Я попробовал для начала просто пропустить этот файл, не конвертировать. Может он один такой аномальный? Но оказалось, что подобных файлов, на которых спотыкается строка $imagick->readImageFile, больше 5%. Это много.
Выяснить, по какой причине происходит это зависание, мне не удалось. Если нет сообщений об ошибках, то нужен не программист, а экстрасенс.
Возможно обновление библиотеки ImageMagick до какой-то версии могло решить эту проблему. Но не стоит заниматься установкой/удалением множества библиотек ради решения одной задачи. Это может повлиять на работоспособность всего хостинга из-за неожиданных конфликтов на других сайтах и программах, использующих ImageMagic текущей версии.
Вторая попытка: Node.js
Если на PHP не выходит, значит, можно попробовать другой язык программирования — JavaScript. И его серверную версию Node.js.
Для работы с SVG были найдены две библиотеки: первая использовала PhantomJS, а вторая — Headless Chrome. Это программы, которые обладают тем же функционалом, что и Chrome-браузер, но не содержат графического интерфейса. С их помощью, например, удобно автоматически делать массовые скриншоты сайтов или имитировать путешествие пользователя по сайту для тестирования. Иными словами, обе библиотеки не преобразовывали SVG в растровую графику самостоятельно, а использовали для этой задачи серверную версию браузера (без графической оболочки). То есть перекладывали всю работу на другие программные компоненты.
При установке мы столкнулись с некоторыми сложностями: библиотеки и их зависимости были установлены, но при попытке сконвертировать SVG в PNG полетели ошибки. Для решения вновь придётся заниматься кропотливой установкой библиотек, соблюдать правильную версионность, искать причины ошибок в сети — на этот раз для node.js.
Современный программист при написании программ массово использует уже готовые библиотеки, написанные и развиваемые кем-то ещё. Это напоминает сборку автомобиля из отдельных узлов и агрегатов.
Но проблема многих модулей и программных библиотек — их несовместимость между собой. Авторы библиотек не успевают за изменениями друг друга. Да и компьютеры и операционные системы у всех разные.
Выход — отказаться от библиотек и использовать чужие готовые программы.
Третья попытка: консольные программы
Консольные программы — это программы без графической оболочки, которые запускаются из командной строки. Их можно запускать изнутри своего PHP-кода. Часто эту возможность ограничивают по соображениям безопасности. Но у меня эта возможность была.
Для начала я попробовал использовать всё тот же ImageMagick.
$cline = ‘convert image.svg image.png’;
Как и с библиотекой ImageMagick программа зависала на некоторых файлах, и ничего не происходило. Видимо, что-то не так в самом ImageMagick, а не в его библиотеках.
После дальнейших поисков удалось найти другую программу для работы с SVG. Это был Inkscape. Установил его, к счастью, без всяких дополнительных библиотек:
sudo apt-get install inkscape
Для конвертации с его помощью нужно делать вот так:
Можно сконвертировать и сразу подогнать изображение под нужную ширину: SVG масштабируется без потерь.
Тестовый код заработал: Inkscape не зависал, как ImageMagick, SVG-файлы конвертировались в PNG. И работал почти в два раза быстрее. Использовал этот код для решения первоначальной задачи и сконвертировал несколько десятков тысяч SVG-файлов для актуального YML-фида: при его изменении новые картинки будут конвертироваться автоматически.
Inkspace может оказаться отличной рабочей альтернативой популярному ImageMagic для решения задач по программной работе.
Удручает, что задачу по конвертации форматов в принципе всё ещё приходится решать: конвертировать данные для экспорта в Google, Facebook, Yandex. Почему IT-гиганты на своей стороне не могут сделать поддержку SVG? Ведь и в их интересах, чтобы товары, объявления или новости на страницах их сервисов были дополнены графикой.
Риторический вопрос, но задача актуальная, хотя прошло уже 10 лет.
Issues to convert SVG to PNG using Imagick
I am trying to convert svg to png image using imagick.This is the code i am using.
My SVG images contain many other base64 encoded images..These images will not convert properly if it is not in png format.
Please help me to fix this issue..Thanks a lot in advance.
1 Answer 1
Do you have the access to the SVG file? Or are you able to download/save it locally, then change
and reference your local downloaded and changed copy?
The other way to show what you need to change is here:
I’m getting then the following:
UPDATE: I’d like to say once more that the SVG file you provided as example has the pink background as with wrong MIME type, as I said in the comments. The problem you describe occurs because of that, no matter how reliable the image source is. You can check it by copying the base64 value of the first in the SVG, decode it and save and then open it with any editor, you will see this:
Now back to your claim that you can’t change all the files. What I can propose is parsing SVG’s XML in your script and replacing all MIME types with the correct ones. Be aware that this will require quite a lot memory as SVG’s may be large. Note the new code between MODIFY THE MALFORMED SVG comments
Convert SVG to transparent PNG with antialiasing, using ImageMagick
I want to convert SVG images to PNG files with transparent background and anti-aliased edges (using semi-transparent pixels). Unfortunately I can’t get ImageMagick to do the anti-aliasing, the edges always look terrible. Here’s what I tried:
Any ideas or a different command line tool I could use?
8 Answers 8
As a side note, I found that getting transparency was a bit tricky. Instead of using transparent, I had to use none.
Inkscape will do this:
Update
The terminology has changed: all the export params suppress gui, and the output parameter is now simply based on the file type. For example, a type of png will cause a file in /path/to/picture.svg to be exported as /path/to/picture.png (caution: this overwrites output).
Also if don’t have Inkscape command line, MacOS can access via bash directly:
Actually, reading imagemagick documentation:
Enable/Disable of the rendering of anti-aliasing pixels when drawing fonts and lines. By default, objects (e.g. text, lines, polygons, etc.) are antialiased when drawn. Use +antialias to disable the addition of antialiasing edge pixels. This will then reduce the
number of colors added to an image to just the colors being directly drawn. That is, no mixed >colors are added when drawing such objects.
the +antialias will indeed disable antialiasing.
How to convert a SVG to a PNG with ImageMagick?
I have a SVG file that has a defined size of 16×16. When I use ImageMagick’s convert program to convert it into a PNG, then I get a 16×16 pixel PNG which is way too small:
But I’m not satisfied, because I want to specify the output size in pixels without doing math to calculate the density value. So I want to do something like this:
So what is the magic parameter I have to use here?
19 Answers 19
I haven’t been able to get good results from ImageMagick in this instance, but Inkscape does a nice job of scaling an SVG on Linux and Windows:
Inkscape 1.0 users, please note that the command line arguments have changed:
Note that you can omit one of the width/height parameters to have the other parameter scaled automatically based on the input image dimensions.
Here’s the result of scaling a 16×16 SVG to a 200×200 PNG using this command:
svgexport is a simple cross-platform command line tool that I have made for exporting svg files to jpg and png, see here for more options. To install svgexport install npm, then run:
Edit: If you find an issue with the library, please submit it on GitHub, thanks!
This is not perfect but it does the job.
Basically it increases the DPI high enough (just use an educated/safe guess) that resizing is done with adequate quality. I was trying to find a proper solution to this but after a while decided this was good enough for my current need.
Note: Use 200×200! to force the given resolution
If you are on MacOS X and having problems with Imagemagick’s convert, you might try reinstalling it with RSVG lib. Using HomeBrew:
Verify that it’s delegating correctly:
Inkscape doesn’t seem to work when svg units are not px (e.g. cm). I got a blank image. Maybe, it could be fixed by twiddling the dpi, but it was too troublesome.
Svgexport is a node.js program and so not generally useful.
Imagemagick’s convert works ok with:
BEST
It is fastest, has the fewest dependencies, and the output is about 30% smaller than convert. Install librsvg2-bin to get it. There does not appear to be a man page but you can type:
to get some assistance. Simple is good.
After following the steps in Jose Alban’s answer, I was able to get ImageMagick to work just fine using the following command:
The number 1536 comes from a ballpark estimate of density, see this answer for more information.
In ImageMagick, one gets a better SVG rendering if one uses Inkscape or RSVG with ImageMagick than its own internal MSVG/XML rendered. RSVG is a delegate that needs to be installed with ImageMagick. If Inkscape is installed on the system, ImageMagick will use it automatically. I use Inkscape in ImageMagick below.
There is no «magic» parameter that will do what you want.
But, one can compute very simply the exact density needed to render the output.
Here is a small 50×50 button when rendered at the default density of 96:
Suppose we want the output to be 500. The input is 50 at default density of 96 (older versions of Inkscape may be using 92). So you can compute the needed density in proportion to the ratios of the dimensions and the densities.
In ImageMagick 7, you can do the computation in-line as follows: