R 语言中的高级图像处理包
阅读原文时间:2023年08月09日阅读:1

最新的 magick 包是为能够在 R 中更现代化、简单化高质量图像处理而进行的一次努力。该包封装了目前最强大的开源图片处理库 ImageMagick STL 。

ImageMagick 库具有大量功能。当前版本的 Magick 公开了很多内容,但是作为第一个发行版本,文档仍然很少。本文简单的介绍了其中一些最重要的概念来帮助了解 magick

安装 magick

在 Windows 或者 MacOS,可以通过 CRAN 安装该软件包。

install.packages("magick")

二进制 CRAN 软件包开箱即用,只需少量的工作,就可以使绝大多数的重要特性得以实现。使用 magick_config 可以查看您的 ImageMagick 版本支持哪些功能和格式。

> library(magick)Linking to ImageMagick 6.9.9.14Enabled features: cairo, freetype, fftw, ghostscript, lcms, pango, rsvg, webpDisabled features: fontconfig, x11

> str(magick::magick_config())List of 21 $ version           :Class 'numeric_version'  hidden list of 1  ..$ : int [1:4] 6 9 9 14 $ modules           : logi FALSE $ cairo             : logi TRUE $ fontconfig        : logi FALSE $ freetype          : logi TRUE $ fftw              : logi TRUE $ ghostscript       : logi TRUE $ jpeg              : logi TRUE $ lcms              : logi TRUE $ libopenjp2        : logi FALSE $ lzma              : logi TRUE $ pangocairo        : logi TRUE $ pango             : logi TRUE $ png               : logi TRUE $ rsvg              : logi TRUE $ tiff              : logi TRUE $ webp              : logi TRUE $ wmf               : logi FALSE $ x11               : logi FALSE $ xml               : logi TRUE $ zero-configuration: logi TRUE

源码编译

Linux 下你需要安装 ImageMagick++ 库。在 Debian/Ubuntu,这个库叫 libmagick++-dev:

sudo apt-get install libmagick++-dev

在 Fedora 或者 CentOS/RHEL 我们需要安装 ImageMagick-c++-devel:

sudo yum install ImageMagick-c++-devel

要从 macOS 上的源代码安装,您需要来自 homebrew 的 imagemagick@6

brew install imagemagick@6

不幸的是,当前 homebrew 上的 imagemagick@6 配置禁用了许多功能,包括 librsvg 和 fontconfig。因此,字体和 svg 渲染的质量可能不是最佳的(建议安装时至少加上 --with-fontconfig--with-librsvg 选项来支持高质量的字体和 svg 渲染。CRAN 上的 OS-Xe 二进制包已经默认配置好了)。

图像输入输出

magick 之所以如此神奇,是因为它会自动转换并呈现所有常见的图像格式。ImageMagick 支持数十种格式并自动检测类型。使用 magick::magick_config() 可以列出您的 ImageMagick 版本支持的格式。

读和写

可以使用 image_read 从图像数据的文件路径,URL 或原始矢量直接读取图像。image_info 函数显示有关图像的一些元数据,类似 于 imagemagick 标识命令行实用程序。

library(magick)tiger&nbsp;<-&nbsp;image_read_svg('http://jeroen.github.io/images/tiger.svg',&nbsp;width&nbsp;=&nbsp;350)print(tiger)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;350&nbsp;&nbsp;&nbsp;&nbsp;350&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

我们使用 image_write 将任何格式的图像导出为磁盘上的文件,或者如果 path = NULL 则导出到内存中的文件。

#&nbsp;Render&nbsp;svg&nbsp;to&nbsp;png&nbsp;bitmapimage_write(tiger,&nbsp;path&nbsp;=&nbsp;"tiger.png",&nbsp;format&nbsp;=&nbsp;"png")

如果 path 是文件名,则 image_write 成功返回 path,以便可以将结果通过文件路径传递给函数。

转换格式

Magick 以原始格式将图像保留在内存中。你可以在 image_write 中通过指定格式参数以转换为另一种格式。或者还可以在应用转换之前,先在内部将图像转换为其他格式。如果你的原始格式是有损的,这将很有用。

tiger_png&nbsp;<-&nbsp;image_convert(tiger,&nbsp;"png")image_info(tiger_png)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;350&nbsp;&nbsp;&nbsp;&nbsp;350&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

预览

具有内置网络浏览器(例如 RStudio)的 IDE 会在查看器中自动显示魔术图像。这就形成了一个整洁的交互式图像编辑环境。

另外,在 Linux 上,您可以使用 image_display 在 X11 窗口中预览图像。最后,image_browse 会在你系统默认的应用程序中为给定类型打开图像。

#&nbsp;X11&nbsp;onlyimage_display(tiger)#&nbsp;System&nbsp;dependentimage_browse(tiger)

另一种方法是将图像转换为栅格对象,然后将其绘制在 R 的图形显示上。但是,这非常慢,并且仅在与其他绘图功能结合使用时才有用。

转变

了解可用转换的最佳方法是遍历 RStudio中 ?transformations 页面中的示例。下面是一些示例。

剪切与编辑

一些转换函数采用了 geometry 参数,该参数需要 AxB + C + D 形式的特殊语法,其中每个元素都是可选的。一些例子:

  • image_crop(image, "100x150+50"): crop out width:100px and height:150px starting +50px from the left

  • image_scale(image, "200"): resize proportionally to width: 200px

  • image_scale(image, "x200"): resize proportionally to height: 200px

  • image_fill(image, "blue", "+100+200"): flood fill with blue starting at the point at x:100, y:200

  • image_border(frink, "red", "20x10"): adds a border of 20px left+right and 10px top+bottom

完整的语法,可以参考 Magick::Geometry 文档。

#&nbsp;Example&nbsp;imagefrink&nbsp;<-&nbsp;image_read("https://jeroen.github.io/images/frink.png")print(frink)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;220&nbsp;&nbsp;&nbsp;&nbsp;445&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;73494&nbsp;&nbsp;&nbsp;72x72

#&nbsp;Add&nbsp;20px&nbsp;left/right&nbsp;and&nbsp;10px&nbsp;top/bottomimage_border(image_background(frink,&nbsp;"hotpink"),&nbsp;"#000080",&nbsp;"20x10")

#&nbsp;Trim&nbsp;marginsimage_trim(frink)

#&nbsp;Passport&nbsp;picaimage_crop(frink,&nbsp;"100x150+50")

#&nbsp;Resizeimage_scale(frink,&nbsp;"300")&nbsp;#&nbsp;width:&nbsp;300px

image_scale(frink,&nbsp;"x300")&nbsp;#&nbsp;height:&nbsp;300px

#&nbsp;Rotate&nbsp;or&nbsp;mirrorimage_rotate(frink,&nbsp;45)

image_flip(frink)

image_flop(frink)

#&nbsp;Brightness,&nbsp;Saturation,&nbsp;Hueimage_modulate(frink,&nbsp;brightness&nbsp;=&nbsp;80,&nbsp;saturation&nbsp;=&nbsp;120,&nbsp;hue&nbsp;=&nbsp;90)

#&nbsp;Paint&nbsp;the&nbsp;shirt&nbsp;orangeimage_fill(frink,&nbsp;"orange",&nbsp;point&nbsp;=&nbsp;"+100+200",&nbsp;fuzz&nbsp;=&nbsp;20)

使用 image_fill,我们可以从像素点开始填充。模糊参数允许填充物穿过具有相似颜色的相邻像素。值必须在 0 到 256^2 之间,指定要视为相等的颜色之间的最大几何距离。在这里,我们给教授 Frink 一件橙色的世界杯衬衫。

滤镜和效果

ImageMagick 还具有许多值得去检查尝试的标准效果。

#&nbsp;Add&nbsp;randomnessimage_blur(frink,&nbsp;10,&nbsp;5)

image_noise(frink)

#&nbsp;Silly&nbsp;filtersimage_charcoal(frink)

image_oilpaint(frink)

image_negate(frink)

核卷积

image_convolve() 函数在图像上实行 kernel 变换。核卷积是指在核矩阵中,图片每个像素的值根据相邻像素的加权和重新计算。例如,让我们看一下这个简单的核变换:

kern&nbsp;<-&nbsp;matrix(0,&nbsp;ncol&nbsp;=&nbsp;3,&nbsp;nrow&nbsp;=&nbsp;3)kern[1,&nbsp;2]&nbsp;<-&nbsp;0.25kern[2,&nbsp;c(1,&nbsp;3)]&nbsp;<-&nbsp;0.25kern[3,&nbsp;2]&nbsp;<-&nbsp;0.25kern

##&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[,1]&nbsp;[,2]&nbsp;[,3]##&nbsp;[1,]&nbsp;0.00&nbsp;0.25&nbsp;0.00##&nbsp;[2,]&nbsp;0.25&nbsp;0.00&nbsp;0.25##&nbsp;[3,]&nbsp;0.00&nbsp;0.25&nbsp;0.00

该核变换将每个像素更改为其水平和垂直相邻像素的平均值,从而在下面的右侧图像中产生轻微的模糊效果:

img&nbsp;<-&nbsp;image_resize(logo,&nbsp;"300x300")img_blurred&nbsp;<-&nbsp;image_convolve(img,&nbsp;kern)image_append(c(img,&nbsp;img_blurred))

或使用任何的 standard kernels:

img&nbsp;%>%&nbsp;image_convolve('Sobel')&nbsp;%>%&nbsp;image_negate()

img&nbsp;%>%&nbsp;image_convolve('DoG:0,0,2')&nbsp;%>%&nbsp;image_negate()

文本注释

最后,在图像的最上层打印输出一些文本往往是十分有用的:

#&nbsp;Add&nbsp;some&nbsp;textimage_annotate(frink,&nbsp;"bioinit",&nbsp;size&nbsp;=&nbsp;70,&nbsp;gravity&nbsp;=&nbsp;"southwest",&nbsp;color&nbsp;=&nbsp;"green")

#&nbsp;Customize&nbsp;textimage_annotate(frink,&nbsp;"Welcome&nbsp;to&nbsp;bioinit",&nbsp;size&nbsp;=&nbsp;30,&nbsp;color&nbsp;=&nbsp;"red",&nbsp;boxcolor&nbsp;=&nbsp;"pink",&nbsp;&nbsp;degrees&nbsp;=&nbsp;60,&nbsp;location&nbsp;=&nbsp;"+50+100")

#&nbsp;Fonts&nbsp;may&nbsp;require&nbsp;ImageMagick&nbsp;has&nbsp;fontconfigimage_annotate(frink,&nbsp;"Hello&nbsp;world,&nbsp;bioinit!",&nbsp;font&nbsp;=&nbsp;'Times',&nbsp;size&nbsp;=&nbsp;30)

大多数平台上支持的字体,包括 "sans""mono""serif""Times""Helvetica""Trebuchet""Georgia""Palatino" ,以及 "Comic Sans"

与管道结合

每个图像转换功能都会返回一个原始图像的修改后的副本。它不会影响原始图像。

frink&nbsp;<-&nbsp;image_read("https://jeroen.github.io/images/frink.png")frink2&nbsp;<-&nbsp;image_scale(frink,&nbsp;"100")image_info(frink)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;220&nbsp;&nbsp;&nbsp;&nbsp;445&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;73494&nbsp;&nbsp;&nbsp;72x72

image_info(frink2)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;100&nbsp;&nbsp;&nbsp;&nbsp;202&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

因此,要组合转换,你需要将它们链接起来:

test&nbsp;<-&nbsp;image_rotate(frink,&nbsp;90)test&nbsp;<-&nbsp;image_background(test,&nbsp;"blue",&nbsp;flatten&nbsp;=&nbsp;TRUE)test&nbsp;<-&nbsp;image_border(test,&nbsp;"red",&nbsp;"10x10")test&nbsp;<-&nbsp;image_annotate(test,&nbsp;"This&nbsp;is&nbsp;how&nbsp;we&nbsp;combine&nbsp;transformations",&nbsp;color&nbsp;=&nbsp;"white",&nbsp;size&nbsp;=&nbsp;30)print(test)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;465&nbsp;&nbsp;&nbsp;&nbsp;240&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

使用 magrittr 管道语法,可以使这一过程更具可读性。

image_read("https://jeroen.github.io/images/frink.png")&nbsp;%>%&nbsp;&nbsp;image_rotate(270)&nbsp;%>%&nbsp;&nbsp;image_background("blue",&nbsp;flatten&nbsp;=&nbsp;TRUE)&nbsp;%>%&nbsp;&nbsp;image_border("red",&nbsp;"10x10")&nbsp;%>%&nbsp;&nbsp;image_annotate("The&nbsp;same&nbsp;thing&nbsp;with&nbsp;pipes",&nbsp;color&nbsp;=&nbsp;"white",&nbsp;size&nbsp;=&nbsp;30)

图像向量

上面的示例涉及的是单个图像。但是,Magick 中的所有函数都已经过向量化,以支持图层、合成或动画的处理。

标准的基本方法 [[[c()length() 可用于处理图像向量,然后可以将其视为图层或帧。

#&nbsp;Download&nbsp;earth&nbsp;gif&nbsp;and&nbsp;make&nbsp;it&nbsp;a&nbsp;bit&nbsp;smaller&nbsp;for&nbsp;vignetteearth&nbsp;<-&nbsp;image_read("https://jeroen.github.io/images/earth.gif")&nbsp;%>%&nbsp;&nbsp;image_scale("200x")&nbsp;%>%&nbsp;&nbsp;image_quantize(128)length(earth)

##&nbsp;[1]&nbsp;44

earth

head(image_info(earth))

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

rev(earth)&nbsp;%>%&nbsp;&nbsp;image_flip()&nbsp;%>%&nbsp;&nbsp;image_annotate("meanwhile&nbsp;in&nbsp;Australia",&nbsp;size&nbsp;=&nbsp;20,&nbsp;color&nbsp;=&nbsp;"white")

图层

我们可以像在 Photoshop 中那样,将图层堆叠在一起:

bigdata&nbsp;<-&nbsp;image_read('https://jeroen.github.io/images/bigdata.jpg')frink&nbsp;<-&nbsp;image_read("https://jeroen.github.io/images/frink.png")logo&nbsp;<-&nbsp;image_read("https://jeroen.github.io/images/Rlogo.png")img&nbsp;<-&nbsp;c(bigdata,&nbsp;logo,&nbsp;frink)img&nbsp;<-&nbsp;image_scale(img,&nbsp;"300x300")image_info(img)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;JPEG&nbsp;&nbsp;&nbsp;300&nbsp;&nbsp;&nbsp;&nbsp;225&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;300&nbsp;&nbsp;&nbsp;&nbsp;232&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;300&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

打印的图案相互镶嵌叠加在一起,从而扩展输出画布,使所有内容都适合:

image_mosaic(img)

Flattening 扁平化处理将各个图层合并成一张与第一张图片大小相同的图片:

image_flatten(img)

Flattening 和 mosaic 处理允许指定其他的复合运算符操作(composite operators):

image_flatten(img,&nbsp;'Add')

image_flatten(img,&nbsp;'Modulate')

image_flatten(img,&nbsp;'Minus')

合并

Appending 追加意味着将框架彼此相邻放置:

image_append(image_scale(img,&nbsp;"x200"))

使用 stack = TRUE 可以将它们放置在彼此的顶部:

image_append(image_scale(img,&nbsp;"100"),&nbsp;stack&nbsp;=&nbsp;TRUE)

合成允许在特定位置上组合两个图像:

bigdatafrink&nbsp;<-&nbsp;image_scale(image_rotate(image_background(frink,&nbsp;"none"),&nbsp;300),&nbsp;"x200")image_composite(image_scale(bigdata,&nbsp;"x400"),&nbsp;bigdatafrink,&nbsp;offset&nbsp;=&nbsp;"+180+100")

页面

当读取 PDF 文档时,每个页面都成为向量的一个元素。注意,PDF 是在读取时呈现的,因此需要立即指定密度。

manual&nbsp;<-&nbsp;image_read_pdf('https://cloud.r-project.org/web/packages/magick/magick.pdf',&nbsp;density&nbsp;=&nbsp;72)image_info(manual)

##&nbsp;&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;11&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;12&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;13&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;14&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;15&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;16&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;17&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;18&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;19&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;20&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;21&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;22&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;23&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;24&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;25&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;26&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;27&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;28&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;29&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;30&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;31&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;32&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;33&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;34&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;35&nbsp;&nbsp;&nbsp;&nbsp;PNG&nbsp;&nbsp;&nbsp;612&nbsp;&nbsp;&nbsp;&nbsp;792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

manual[1]

动画

除了将矢量元素视为图层之外,我们还可以将它们制作成动画帧!

image_animate(image_scale(img,&nbsp;"200x200"),&nbsp;fps&nbsp;=&nbsp;1,&nbsp;dispose&nbsp;=&nbsp;"previous")

变形创建了 n 个图像序列,这些序列逐渐地将一个图像变形为另一个图像。这样,它就变成了动画。

newlogo&nbsp;<-&nbsp;image_scale(image_read("https://jeroen.github.io/images/Rlogo.png"),&nbsp;"x150")oldlogo&nbsp;<-&nbsp;image_scale(image_read("https://developer.r-project.org/Logo/Rlogo-3.png"),&nbsp;"x150")frames&nbsp;<-&nbsp;image_morph(c(oldlogo,&nbsp;newlogo),&nbsp;frames&nbsp;=&nbsp;10)image_animate(frames)

如果您读入现有的 GIF 或视频文件,则每一帧都会变成一个图层:

#&nbsp;Foreground&nbsp;imagebanana&nbsp;<-&nbsp;image_read("https://jeroen.github.io/images/banana.gif")banana&nbsp;<-&nbsp;image_scale(banana,&nbsp;"150")image_info(banana)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;GIF&nbsp;&nbsp;&nbsp;150&nbsp;&nbsp;&nbsp;&nbsp;148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

处理各个帧并将其放回动画中:

#&nbsp;Background&nbsp;imagebackground&nbsp;<-&nbsp;image_background(image_scale(logo,&nbsp;"200"),&nbsp;"white",&nbsp;flatten&nbsp;=&nbsp;TRUE)#&nbsp;Combine&nbsp;and&nbsp;flatten&nbsp;framesframes&nbsp;<-&nbsp;image_composite(background,&nbsp;banana,&nbsp;offset&nbsp;=&nbsp;"+70+30")#&nbsp;Turn&nbsp;frames&nbsp;into&nbsp;animationanimation&nbsp;<-&nbsp;image_animate(frames,&nbsp;fps&nbsp;=&nbsp;10)print(animation)

##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72##&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;gif&nbsp;&nbsp;&nbsp;200&nbsp;&nbsp;&nbsp;&nbsp;155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sRGB&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;72x72

动画可以另存为 GIF 格式的 MPEG 文件:

image_write(animation,&nbsp;"Rlogo-banana.gif")

绘图与图形

该软件包的一个相对较新的组件是一个本地的 R 图形设备,它生成 magick 图像对象。它可以像用于绘制绘图的常规设备一样使用它,也可以打开一个使用像素坐标绘制到现有图像的设备。

图形设备

image_graph() 函数可打开一个新的图形设备,类似于 png()x11() 。它返回要写入绘图的图像对象。绘图设备中的每个“page”都将成为图像对象中的一帧。

#&nbsp;Produce&nbsp;image&nbsp;using&nbsp;graphics&nbsp;devicefig&nbsp;<-&nbsp;image_graph(width&nbsp;=&nbsp;400,&nbsp;height&nbsp;=&nbsp;400,&nbsp;res&nbsp;=&nbsp;96)ggplot2::qplot(mpg,&nbsp;wt,&nbsp;data&nbsp;=&nbsp;mtcars,&nbsp;colour&nbsp;=&nbsp;cyl)dev.off()

我们可以使用常规图像操作轻松地对图形进行后处理。

#&nbsp;Combineout&nbsp;<-&nbsp;image_composite(fig,&nbsp;frink,&nbsp;offset&nbsp;=&nbsp;"+70+30")print(out)

##&nbsp;#&nbsp;A&nbsp;tibble:&nbsp;1&nbsp;x&nbsp;7##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;&nbsp;&nbsp;<chr>&nbsp;&nbsp;<int>&nbsp;&nbsp;<int>&nbsp;<chr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<lgl>&nbsp;&nbsp;&nbsp;&nbsp;<int>&nbsp;<chr>##&nbsp;1&nbsp;PNG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;400&nbsp;&nbsp;&nbsp;&nbsp;400&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72

绘图设备

使用图形设备的另一种方法是使用像素坐标在现有图像的上面绘制。

#&nbsp;Or&nbsp;paint&nbsp;over&nbsp;an&nbsp;existing&nbsp;imageimg&nbsp;<-&nbsp;image_draw(frink)rect(20,&nbsp;20,&nbsp;200,&nbsp;100,&nbsp;border&nbsp;=&nbsp;"red",&nbsp;lty&nbsp;=&nbsp;"dashed",&nbsp;lwd&nbsp;=&nbsp;5)abline(h&nbsp;=&nbsp;300,&nbsp;col&nbsp;=&nbsp;'blue',&nbsp;lwd&nbsp;=&nbsp;'10',&nbsp;lty&nbsp;=&nbsp;"dotted")text(30,&nbsp;250,&nbsp;"Hoiven-Glaven",&nbsp;family&nbsp;=&nbsp;"monospace",&nbsp;cex&nbsp;=&nbsp;4,&nbsp;srt&nbsp;=&nbsp;90)palette(rainbow(11,&nbsp;end&nbsp;=&nbsp;0.9))symbols(rep(200,&nbsp;11),&nbsp;seq(0,&nbsp;400,&nbsp;40),&nbsp;circles&nbsp;=&nbsp;runif(11,&nbsp;5,&nbsp;35),&nbsp;&nbsp;bg&nbsp;=&nbsp;1:11,&nbsp;inches&nbsp;=&nbsp;FALSE,&nbsp;add&nbsp;=&nbsp;TRUE)dev.off()

print(img)

##&nbsp;#&nbsp;A&nbsp;tibble:&nbsp;1&nbsp;x&nbsp;7##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;&nbsp;&nbsp;<chr>&nbsp;&nbsp;<int>&nbsp;&nbsp;<int>&nbsp;<chr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<lgl>&nbsp;&nbsp;&nbsp;&nbsp;<int>&nbsp;<chr>##&nbsp;1&nbsp;PNG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;220&nbsp;&nbsp;&nbsp;&nbsp;445&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72

默认情况下,image_draw() 将所有空白设置为 0,并使用图形坐标来匹配图像大小,像素(宽度x高度)为左上角 (0,0)。注意,这意味着 y 轴从上到下递增,这与典型的图形坐标相反。您可以通过向 image_draw 传递定制的 xlimylimmar 值来覆盖所有这些。

动画图形

图形设备支持多帧,这使它很容易创建动画图形。下面的代码展示了如何使用 magick 图形设备实现来自非常酷的 gganimate 包的示例。

library(gapminder)library(ggplot2)img&nbsp;<-&nbsp;image_graph(600,&nbsp;340,&nbsp;res&nbsp;=&nbsp;96)datalist&nbsp;<-&nbsp;split(gapminder,&nbsp;gapminder$year)out&nbsp;<-&nbsp;lapply(datalist,&nbsp;function(data){&nbsp;&nbsp;p&nbsp;<-&nbsp;ggplot(data,&nbsp;aes(gdpPercap,&nbsp;lifeExp,&nbsp;size&nbsp;=&nbsp;pop,&nbsp;color&nbsp;=&nbsp;continent))&nbsp;+&nbsp;&nbsp;&nbsp;&nbsp;scale_size("population",&nbsp;limits&nbsp;=&nbsp;range(gapminder$pop))&nbsp;+&nbsp;geom_point()&nbsp;+&nbsp;ylim(20,&nbsp;90)&nbsp;+&nbsp;&nbsp;&nbsp;&nbsp;scale_x_log10(limits&nbsp;=&nbsp;range(gapminder$gdpPercap))&nbsp;+&nbsp;ggtitle(data$year)&nbsp;+&nbsp;theme_classic()&nbsp;&nbsp;print(p)})dev.off()animation&nbsp;<-&nbsp;image_animate(img,&nbsp;fps&nbsp;=&nbsp;2)print(animation)

##&nbsp;#&nbsp;A&nbsp;tibble:&nbsp;12&nbsp;x&nbsp;7##&nbsp;&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;&nbsp;&nbsp;&nbsp;<chr>&nbsp;&nbsp;<int>&nbsp;&nbsp;<int>&nbsp;<chr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<lgl>&nbsp;&nbsp;&nbsp;&nbsp;<int>&nbsp;<chr>##&nbsp;&nbsp;1&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;2&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;3&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;4&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;5&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;6&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;7&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;8&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;&nbsp;9&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;10&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;11&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72##&nbsp;12&nbsp;gif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;600&nbsp;&nbsp;&nbsp;&nbsp;340&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;72x72

要将其写入文件,您只需执行以下操作:

image_write(animation,&nbsp;"gapminder.gif")

光栅图像

Magick 图像也可以转换为光栅对象,来用于 R 的图形设备。因此,我们可以将它与其他图形工具相结合。然而,请注意,R 的图形设备非常慢,且它有一个非常不同的坐标系,它会降低图像的质量。

基础格栅

Base R 有一个 as.raster 格式,它可将图像转换为字符串向量。Paul Murrell 在  Raster Images in R Graphics 一文中给出了一个很好的概述。

plot(as.raster(frink))

#&nbsp;Print&nbsp;over&nbsp;another&nbsp;graphicplot(cars)rasterImage(frink,&nbsp;21,&nbsp;0,&nbsp;25,&nbsp;80)

grid 包

grid 包使您更容易在图形设备上叠加栅格,而不必调整绘图的 x/y 坐标。

library(ggplot2)library(grid)qplot(speed,&nbsp;dist,&nbsp;data&nbsp;=&nbsp;cars,&nbsp;geom&nbsp;=&nbsp;c("point",&nbsp;"smooth"))

##&nbsp;`geom_smooth()`&nbsp;using&nbsp;method&nbsp;=&nbsp;'loess'&nbsp;and&nbsp;formula&nbsp;'y&nbsp;~&nbsp;x'

grid.raster(frink)

raster 包

raster 包具有自己的 bitmaps 类,这些类对于空间应用程序很有用。将图像转换为栅格的最简单方法是将其导出为 tiff 文件:

tiff_file&nbsp;<-&nbsp;tempfile()image_write(frink,&nbsp;path&nbsp;=&nbsp;tiff_file,&nbsp;format&nbsp;=&nbsp;'tiff')r&nbsp;<-&nbsp;raster::brick(tiff_file)raster::plotRGB(r)

你还可以手动将位图数组(bitmap array )转换为栅格对象,但这似乎会删除一些元数据:

buf&nbsp;<-&nbsp;as.integer(frink[[1]])rr&nbsp;<-&nbsp;raster::brick(buf)raster::plotRGB(rr,&nbsp;asp&nbsp;=&nbsp;1)

OCR 文本提取

magick 最新的功能是利用 OCR 技术从图片中提取文本。这需要 tesseract 包。

install.packages("tesseract")

img&nbsp;<-&nbsp;image_read("http://jeroen.github.io/images/testocr.png")print(img)

##&nbsp;#&nbsp;A&nbsp;tibble:&nbsp;1&nbsp;x&nbsp;7##&nbsp;&nbsp;&nbsp;format&nbsp;width&nbsp;height&nbsp;colorspace&nbsp;matte&nbsp;filesize&nbsp;density##&nbsp;&nbsp;&nbsp;<chr>&nbsp;&nbsp;<int>&nbsp;&nbsp;<int>&nbsp;<chr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<lgl>&nbsp;&nbsp;&nbsp;&nbsp;<int>&nbsp;<chr>##&nbsp;1&nbsp;PNG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;640&nbsp;&nbsp;&nbsp;&nbsp;480&nbsp;sRGB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;23359&nbsp;72x72

#&nbsp;Extract&nbsp;textcat(image_ocr(img))

##&nbsp;This&nbsp;is&nbsp;a&nbsp;lot&nbsp;of&nbsp;12&nbsp;point&nbsp;text&nbsp;to&nbsp;test&nbsp;the##&nbsp;ocr&nbsp;code&nbsp;and&nbsp;see&nbsp;if&nbsp;it&nbsp;works&nbsp;on&nbsp;all&nbsp;types##&nbsp;of&nbsp;file&nbsp;format.####&nbsp;The&nbsp;quick&nbsp;brown&nbsp;dog&nbsp;jumped&nbsp;over&nbsp;the##&nbsp;lazy&nbsp;fox.&nbsp;The&nbsp;quick&nbsp;brown&nbsp;dog&nbsp;jumped##&nbsp;over&nbsp;the&nbsp;lazy&nbsp;fox.&nbsp;The&nbsp;quick&nbsp;brown&nbsp;dog##&nbsp;jumped&nbsp;over&nbsp;the&nbsp;lazy&nbsp;fox.&nbsp;The&nbsp;quick##&nbsp;brown&nbsp;dog&nbsp;jumped&nbsp;over&nbsp;the&nbsp;lazy&nbsp;fox.

总结

本文章篇幅很长,对 magick 包的各种使用非常直观详细。作为与 ImageMagick 绑定,可用的最全面的开源图像处理库,magick 包支持许多常见格式(png,jpeg,tiff,pdf 等)和操作(旋转,缩放,修剪,修剪,翻转,模糊等)。这些所有操作都是通过 Magick ++ STL 矢量化的,这意味着它们可以在单个帧或一系列帧上进行操作,以处理图层,拼贴或动画。

在 RStudio 中,可以将图像打印到控制台后会自动预览,从而形成一个交互式编辑环境。因此,强烈推荐大家在 RStudio 中进行使用和测试。

更多 magick、ImageMagick 相关的 R 语言高级图像处理操作,有兴趣的童鞋可以自行去研究学习,也欢迎大家留言交流。

参考资料:

https://cran.r-project.org/web/packages/magick/vignettes/intro.html

——The  End——

本文分享自微信公众号 - 生信科技爱好者(bioitee)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。