Использование сетки для создания и сохранения небольшого файла png

Я использую R для создания небольшого количества графики, которая будет сохранена в виде файлов PNG, обычно размером 50x50 пикселей, которые в конечном итоге будут использоваться в гораздо большем изображении в качестве значков или маркеров. Поскольку содержимое часто меняется, желательно, чтобы они создавались программно, а не вручную.

Поскольку содержание также простое — несколько символов текста и несколько чисел — функции grid кажутся простым способом решить эту проблему. Я совсем не знаю grid, так как обычно использую библиотеки более высокого уровня, такие как ggplot2. MRE ниже излагает то, что я уже достиг.

Это генерирует выходные данные, но у меня возникают проблемы с привязкой размеров и масштабов viewport и различных grobs к окончательному файлу PNG. То, что я получаю, это изображение ниже, которое на первый взгляд хорошо, но это изображение размером 480x480 пикселей, большая часть которого не используется, а центральная графика занимает только треть ширины и высоты.

Это кажется логичным, учитывая размер области просмотра (=.3), но если я увеличу область просмотра, то, по-видимому, мне придется увеличить текст и так далее. (Я знаю, как изменить параметры png(), чтобы отрегулировать плотность, количество пикселей и так далее, но на данный момент проблема заключается в самом изображении.)

Вопрос сводится к тому, как лучше всего создать файл PNG или SVG достойного качества размером 50x50 пикселей из такой графики, созданной в R, либо с использованием grid, либо каким-либо другим подходом.

Вывод файла PNG

library(grid)
grid.newpage()
png(bg = "transparent")
pushViewport(viewport(width=.3, height=.3, clip="off"))
grid.rect(gp=gpar(lty=0, fill="#008000"))
grid.text("15.5", x = unit(0.5, "npc"), y = unit(0.75, "npc"),
          just = "center", hjust = NULL, vjust = NULL, rot = 0,
          check.overlap = FALSE, default.units = "npc",
          name = NULL, gp = gpar(fontsize=48), draw = TRUE, vp = NULL)

grid.text("13h 20m", x = unit(0.5, "npc"), y = unit(0.25, "npc"),
          just = "center", hjust = NULL, vjust = NULL, rot = 0,
          check.overlap = FALSE, default.units = "npc",
          name = NULL, gp = gpar(fontsize=32), draw = TRUE, vp = NULL)

lg <- linesGrob(x = unit(c(0, 1), "npc"),
                y = unit(c(0.5, 0.5), "npc"),
                gp = gpar(lwd=2))
grid.draw(lg)
dev.off()

person SlowLearner    schedule 10.08.2019    source источник
comment
В конечном итоге вам нужно ограничить размер с помощью png('test.png', width = 50, height = 50, bg = "transparent"), но вам придется настроить размеры того, что вы рисуете, чтобы они соответствовали этому устройству.   -  person alistaire    schedule 10.08.2019
comment
Спасибо. Именно осмысление настроек размера, а не метод проб и ошибок, вызывает у меня проблемы. Могу ли я создать его в большем размере и изменить его размер при сохранении, что-то в этом роде.   -  person SlowLearner    schedule 10.08.2019
comment
Вы не можете легко изменить размер, потому что вы открываете устройство перед рисованием. Единицы npc позаботятся о большей части относительных размеров для вас, но вам нужно удалить width и height из viewport, чтобы он использовал значения npc по умолчанию (это то, что вам нужно), и уменьшить fontsize, что не может быть npc (16 и 12 выглядят примерно так). Обобщая, вы можете хотя бы начать с SVG вместо PNG, поскольку первые предназначены для хорошего масштабирования.   -  person alistaire    schedule 10.08.2019


Ответы (1)


В этом может помочь библиотека magic. Я использовал ваши начальные коды для создания пустого файла png.

library(grid)
grid.newpage()
png(bg = "transparent")
pushViewport(viewport(width=.3, height=.3, clip="off"))
dev.off()

Затем я прочитал этот png-файл, чтобы поместить его в коды magic, как показано ниже. На самом деле может существовать способ поместить файл png непосредственно в magic в вашем сеансе R, не создавая временных операций записи-чтения. Однако, если у вас есть много файлов для создания и сохранения в формате png, не так важно один раз прочитать пустой файл png. Так как его можно использовать как для всех новых выходов.

library(magick)

img <- image_read("./desktop/Rplot001.png")

output <- img %>% image_background("#008000") %>% image_resize("50x50") %>% 
          image_annotate("15.5", size = 17, gravity = "north", location = "+1+4",color = "black", boxcolor = NULL) %>% 
          image_annotate("13h 20m", size = 11, gravity = "south", location = "+0+7",color = "black", boxcolor = NULL)

image_write(output, path = "./desktop/output.png", format = "png")

Он дает файл png 50x50,

введите здесь описание изображения

person maydin    schedule 10.08.2019
comment
Спасибо - на самом деле я использую Imagemagick и библиотеку magick для другой части рабочего процесса, но я хотел бы улучшить исходное изображение, созданное в R. - person SlowLearner; 10.08.2019