настройка плотности при чтении изображения с помощью RMagick

#ruby #vector #svg #imagemagick #rmagick

#ruby #вектор #svg #imagemagick #rmagick

Вопрос:

Я пытаюсь использовать RMagick для преобразования SVG в PNG другого размера.

Когда я читаю в SVG с помощью Magick::Image.read('drawing.svg') и записываю его в drawing.png (эквивалент простого запуска convert drawing.svg drawing.png из командной строки), размер составляет 744×1052.

Предположим, я хочу, чтобы PNG был в два раза больше, чем по умолчанию. Вы не можете просто прочитать его, изменить его размер, а затем записать, поскольку это сначала растрирует SVG, а затем масштабирует это изображение в два раза больше, теряя качество и все преимущества использования векторной графики в первую очередь. Итак, вместо этого, если я правильно понимаю, вы должны установить плотность изображения при чтении.

 image = Magick::Image.read('drawing.svg'){self.density = 144}.first
  

Но image.density плотность по-прежнему отображается как «72×72», и если я выпишу изображение, оно будет того же размера, что и раньше, 744×1052. Кажется, не имеет значения, как я указываю плотность при чтении. С помощью 144, «144», 144.0, «144.0», » 144×144″ и «144.0×144.0», он всегда возвращает «72×72».

Запуск convert -density 144 drawing.svg drawing.png из командной строки работает как ожидалось и генерирует формат PNG, который в два раза больше, чем раньше, 2104×1488.

Я использую OS X 10.6.7, ImageMagick 6.7.0-0 (устанавливается через MacPorts), RMagick 2.13.1 и Ruby 1.9.2p180. Когда я помещаю свой код в контекст небольшого веб-приложения Sinatra на Heroku, у него такое же некорректное поведение, так что проблема, похоже, связана не с OS X или MacPorts.

Ответ №1:

Плотность — это разрешение (т. Е. точки на дюйм), а не размер отображаемого изображения. Из точного руководства:

Разрешение изображения по вертикали и горизонтали в пикселях. Значение по умолчанию равно «72×72».

Я думаю, вы ищете resize или resize! :

Изменяет размер приемника до заданных размеров.

Вы можете указать новый размер двумя способами. Либо укажите новые ширину и высоту явно, либо укажите масштабный коэффициент, число, представляющее процентное изменение.

Итак, это сработает:

 Magick::Image.read('drawing.svg').first.resize(2).write('drawing.png')
  

Или это:

 img = Magick::Image.read('drawing.svg').first
img.resize!(2)
img.write('drawing.png')
  

Я не знаю, почему convert ведет себя иначе, чем библиотека, в play могут быть другие настройки по умолчанию, которые имеют разные значения по умолчанию в библиотеке, или, возможно, -density это больше, чем установка плотности.

Если resize у вас ничего не получается (и, судя по вашим комментариям, это происходит слишком поздно, чтобы быть полезным), вы можете попробовать установить size параметр в блоке:

 img = Magick::Image.read('drawing.svg'){ |opts| opts.size = '2104x1488' }.first
  

Конечно, вы должны заранее знать, насколько велик SVG. Предполагается, что вы можете указывать такие вещи, как 200%x200% для геометрии, но read всегда игнорирует флаг на Magick::Geometry , когда я пытаюсь это сделать.

Комментарии:

1. Если бы я просто работал с преобразованием растра в растр, изменение размера определенно было бы тем, что я хотел. Но если я изменяю размер после того, как SVG был прочитан, я увеличиваю масштаб растрового изображения, и поэтому я получаю неприятные артефакты сглаживания , которые вы ожидаете. convert Команда, похоже, в первую очередь растрирует SVG как увеличенное изображение, что создает должным образом плавные линии .

2. Это не позволило бы мне отредактировать мой комментарий, но я хотел упомянуть тему, которую я нашел на форумах ImageMagick , в которой говорится, что одним из способов использования -density является указание плотности чтения для векторного изображения. Это просто, по-видимому, не имеет того же значения для RMagick, что и для convert .

3. @hynkle: Взгляните на мое обновление. Предполагается, что вы можете указать геометрию в процентах для opts.size , но я не могу заставить это работать или выдать сообщение об ошибке, в котором говорится, почему это не сработает. Хотя это довольно типично для моих взаимодействий с ImageMagick: отличная библиотека, если вы можете заставить ее работать, ужасный интерфейс.

4. @muistoosh short похоже, это больше не работает. Я пробовал это, но выбор в пользу изменения.размер ни на что не влияет.