我有几个图标(技术上是 sRGB,但大多是黑色或白色,具有透明背景)。我想将颜色更改为
darkblue
(比如说)。
因此每个图标都由透明背景和黑色或白色前景组成,我想将此颜色更改为我选择的颜色。
NB. 我正在使用这张图片,因为它附带
magick
(这使得示例更容易重现),即使它与我的真实案例不同。我们假设白色条代表背景,黑色区域代表我的前景。
library(magick)
pic <- image_read(file.path(system.file(package = "magick"),
"images", "shape_rectangle.gif"))
## find dark spot and use `image_fill`
pixels <- pic |>
image_data() |>
as.integer()
(idx <- which(pixels[, , 3] == max(pixels[, , 3]), arr.ind = TRUE)[1, ])
# row col
# 49 25
image_fill(pic, "darkblue", "+49+25")
虽然这种方法在这个简单的情况下有效,但我对我的真实图标的“解决方案”并不满意。徽标可以由多个“区域”组成,虽然我可以填充所有黑点,但这似乎首先是一种完全的杀伤力,我认为有一个功能更适合此任务,而不是洪水填充该区域。
原则上,我想在
R
中执行与在命令行中所做的完全相同的操作:How to colorize a black-transparent PNG icon with ImageMagick
因此,我认为我识别黑点和洪水填充的想法并不是解决这个问题的正确方法,我很高兴了解哪些
magick
函数更适合手头的任务。
这是我的徽标的真实示例。您可以看到有一个断开的盖子,并且所选的方法无法为每个区域着色。
经过更多研究,我找到了一个相当优雅的解决方案:
CopyOpacity
作为操作符,用彩色背景和蒙版组成一张图片,(据我所知)复制不透明度,将背景的不透明度设置为 0 并仅保留前景 et voilàchange_icon_color <- function(pic, new_color) {
dims <- pic %>%
image_info()
mask <- pic %>%
image_channel("alpha") %>%
image_negate()
image_blank(dims$width, dims$height, new_color) %>%
image_composite(mask, operator = "CopyOpacity")
}
## N.B. in this toy example we need to explicitly set the transparency
change_icon_color(pic %>% image_transparent("white"), "forestgreen")