使用带有转换的 Magick(在 R 中)处理多个图像
Processing multiple images with Magick (in R) with transformations
我需要自动执行一些图像转换以执行以下操作:
- 阅读 16,000 多张短而宽的图像,尺寸不一样。
- 将每个图像重新调整为 90 像素高
- 在图像的宽度上裁剪 90 像素,因此在一张图像上裁剪多个 90x90 - 然后为下一张图像重新做一遍
- 每个 90x90 图像需要保存为 file-name_1.png、file-name_2.png 等顺序
我已经完成了 8 张图像的测试,使用 magick 包我能够手动重新缩放每张图像并创建多个裁剪。问题是当我尝试做多个时,我可以很容易地调整图像的大小,但是在保存它们时出现了问题。
# capture images, file paths in a list
img_list <- list.files("./orig_images", pattern = "\.png$", full.names = TRUE)
# get all images in a list
all_images <- lapply(img_list, image_read)
# scale each image height - THIS DOESN'T WORK, GET NULL VALUE
scale_images <-
for (i in 1:length(all_images)) {
scale_images(all_images[[i]], "x90")
}
# all images added into one
all_images_joined <- image_join(all_images)
# scale images - THIS WORKS to scale, but problems later
all_images_scaled <-
image_scale(all_images_joined, "x90")
# Test whether a single file will be written or multiple files;
# only writes one file (even if I
for (i in 1:length(all_images_scaled)) {
image_write(all_images_scaled[[i]], path = "filepath/new_cropimages/filename")
}
理想情况下,我会使用 for 循环缩放图像。这样我就可以将缩放后的图像保存到一个目录中。这没有用——我没有收到错误,但是当我检查变量的内容时它是空的。 image_join 函数将它们放在一起并将高度缩放为 90(宽度也按比例缩放)但我无法将单独的图像写入目录。此外,下一部分是跨宽度裁剪每个图像并保存新图像文件-name_1.png,对于每个 90x90 图像,移动超过 90 像素,裁剪 90x90,依此类推。我选择 magic 是因为它很容易单独缩放和裁剪,但我对其他想法持开放态度(或学习如何使该包工作)。感谢您的帮助。
这是一些图片:
[Original Image, untransformed][1]
[Manual 90x90 crop][2]
[Another manual 90x90 crop, farther down the same image][3]
[1]: https://i.stack.imgur.com/8ptXv.png
[2]: https://i.stack.imgur.com/SF9pG.png
[3]: https://i.stack.imgur.com/NyKxS.png
我不会说 R,但我希望能够在 ImageMagick 方面提供帮助并处理 16,000 张图像。
当你在 Mac 上时,你可以使用 homebrew 非常轻松地安装 2 个非常有用的包,使用:
brew install imagemagick
brew install parallel
所以,您的原始句子图像是 1850x105 像素,您可以在终端中看到这样的图像:
magick identify sentence.png
sentence.png PNG 1850x105 1850x105+0+0 8-bit Gray 256c 51626B 0.000u 0:00.000
如果将高度调整为 90px,宽度按比例调整,它将变为 1586x90px:
magick sentence.png -resize x90 info:
sentence.png PNG 1586x90 1586x90+0+0 8-bit Gray 51626B 0.060u 0:00.006
因此,如果您调整大小然后裁剪成 90 像素宽的块:
magick sentence.png -resize x90 -crop 90x chunk-%03d.png
你将得到 18 个块,除最后一个外,每个块宽 90 像素,如下所示:
-rw-r--r-- 1 mark staff 5648 6 Jun 08:07 chunk-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:07 chunk-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:07 chunk-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:07 chunk-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:07 chunk-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:07 chunk-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:07 chunk-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:07 chunk-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:07 chunk-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:07 chunk-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:07 chunk-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:07 chunk-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:07 chunk-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:07 chunk-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:07 chunk-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:07 chunk-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:07 chunk-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:07 chunk-017.png
现在,如果您有 16,000 个句子要处理,您可以使用 GNU Parallel 并行完成它们,并为所有文件获取合理的名称。让我们先做一个 dry-run 所以它实际上什么都不做,只是告诉你它会做什么:
parallel --dry-run magick {} -resize x90 -crop 90x {.}-%03d.png ::: sentence*
示例输出
magick sentence1.png -resize x90 -crop 90x sentence1-%03d.png
magick sentence2.png -resize x90 -crop 90x sentence2-%03d.png
magick sentence3.png -resize x90 -crop 90x sentence3-%03d.png
这看起来不错,所以删除 --dry-run
并再次执行,对于我所做的三个(相同副本)句子,您将得到以下输出:
-rw-r--r-- 1 mark staff 5648 6 Jun 08:13 sentence1-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:13 sentence1-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:13 sentence1-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:13 sentence1-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:13 sentence1-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:13 sentence1-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:13 sentence1-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:13 sentence1-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:13 sentence1-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:13 sentence1-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:13 sentence1-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:13 sentence1-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:13 sentence1-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:13 sentence1-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:13 sentence1-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:13 sentence1-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:13 sentence1-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:13 sentence1-017.png
-rw-r--r-- 1 mark staff 5648 6 Jun 08:13 sentence2-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:13 sentence2-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:13 sentence2-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:13 sentence2-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:13 sentence2-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:13 sentence2-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:13 sentence2-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:13 sentence2-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:13 sentence2-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:13 sentence2-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:13 sentence2-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:13 sentence2-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:13 sentence2-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:13 sentence2-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:13 sentence2-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:13 sentence2-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:13 sentence2-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:13 sentence2-017.png
-rw-r--r-- 1 mark staff 5648 6 Jun 08:13 sentence3-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:13 sentence3-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:13 sentence3-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:13 sentence3-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:13 sentence3-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:13 sentence3-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:13 sentence3-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:13 sentence3-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:13 sentence3-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:13 sentence3-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:13 sentence3-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:13 sentence3-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:13 sentence3-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:13 sentence3-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:13 sentence3-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:13 sentence3-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:13 sentence3-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:13 sentence3-017.png
关于parallel
参数的解释:
{}
指的是"the current file"
{.}
指的是"the current file without its extension"
:::
将用于 parallel
的参数与用于 magick
命令的参数分开
请注意,PNG 图像可以 "remember" 它们的来源可能有用,也可能非常烦人。如果你从上面看最后一个块,你会看到它是 56x90,但紧随其后的是 "remembers" 它来自 canvas 1586x90,偏移量为 1530 ,0:
identify sentence3-017.png
sentence3-017.png PNG 56x90 1586x90+1530+0 8-bit Gray 256c 4848B 0.000u 0:00.000
这有时会打乱令人讨厌的后续处理,或者有时在 re-assembling 被切碎的图像中非常有用!如果要去掉,需要重新分页,所以上面的命令就变成了:
magick input.png -resize x90 -crop 90x +repage output.png
已更新 - 更好地利用 EBImage 中的工具
ImageMagick 是一个很好的方法。但是如果您想对图像执行一些内容分析,这里有一个使用 R 的解决方案。R 确实提供了一些非常方便的工具。此外,图像只是矩阵,R 处理得很好。通过将图像缩减为矩阵,包 EBImage
做得很好,并且无论好坏,都删除了每个图像的一些元数据。这是 EBImage
的 R 解决方案。不过,Mark 的解决方案可能更适合真正的大批量生产。
解决方案是围绕一个大的“for”循环构建的。在几个步骤中添加错误检查是明智的。该代码利用 EBImage
来管理彩色和灰度图像。
在这里,通过添加所需背景颜色的像素,最终图像在扩展图像中居中。然后将扩展图像裁剪成图块。如果需要,可以调整确定 pad
值的逻辑以简单地裁剪图像或左对齐或右对齐。
首先假设您从工作目录开始,源文件在 ./source
中,目标文件在 ./dest
中。它还为每个“平铺”图像创建一个新目录。这可以更改为让一个目录接收所有图像以及其他保护编码。此处,假定图像是具有适当扩展名的 PNG 文件。要应用于高度和宽度的所需图块大小 (90) 存储在变量 size
.
中
# EBImage needs to be available
if (!require(EBImage)) {
source("https://bioconductor.org/biocLite.R")
biocLite("EBImage")
library(EBImage)
}
# From the working directory, select image files
size <- 90
bg.col <- "transparent" # or any other color specification for R
ff <- list.files("source", full = TRUE,
pattern = "png$", ignore.case = TRUE)
# Walk through all files with a 'for' loop,
for (f in ff) {
# Extract base name, even names like "foo.bar.1.png"
txt <- unlist(strsplit(basename(f), ".", fixed = TRUE))
len <- length(txt)
base <- ifelse(len == 1, txt[1], paste(txt[-len], collapse = "."))
# Read one image and resize
img <- readImage(f)
img <- resize(img, h = size) # options allow for antialiasing
# Determine number tiles and padding needed
nx <- ceiling(dim(img)[1]/size)
newdm <- c(nx * size, size) # extend final image
pad <- newdm[1] - dim(img)[1] # pixels needed to extend
# Translate the image with given background fille
img <- translate(img, c(pad%/%2, 0), output.dim = newdm, bg.col = bg.col)
# Split image into appropriate sized tiles with 'untile'
img <- untile(img, c(nx, 1), lwd = 0) # see the help file
# Create a new directory for each image
dpath <- file.path("dest", trimws(base)) # Windows doesn't like " "
if (!dir.create(dpath))
stop("unable to create directory: ", dpath)
# Create new image file names for each frame
fn <- sprintf("%s_%03d.png", base, seq_len(nx))
fpaths <- file.path(dpath, fn)
# Save individual tiles (as PNG) and names of saved files
saved <- mapply(writeImage, x = getFrames(img, type = "render"),
files = fpaths)
# Check on the results from 'mapply'
print(saved)
}
我需要自动执行一些图像转换以执行以下操作: - 阅读 16,000 多张短而宽的图像,尺寸不一样。 - 将每个图像重新调整为 90 像素高 - 在图像的宽度上裁剪 90 像素,因此在一张图像上裁剪多个 90x90 - 然后为下一张图像重新做一遍 - 每个 90x90 图像需要保存为 file-name_1.png、file-name_2.png 等顺序
我已经完成了 8 张图像的测试,使用 magick 包我能够手动重新缩放每张图像并创建多个裁剪。问题是当我尝试做多个时,我可以很容易地调整图像的大小,但是在保存它们时出现了问题。
# capture images, file paths in a list
img_list <- list.files("./orig_images", pattern = "\.png$", full.names = TRUE)
# get all images in a list
all_images <- lapply(img_list, image_read)
# scale each image height - THIS DOESN'T WORK, GET NULL VALUE
scale_images <-
for (i in 1:length(all_images)) {
scale_images(all_images[[i]], "x90")
}
# all images added into one
all_images_joined <- image_join(all_images)
# scale images - THIS WORKS to scale, but problems later
all_images_scaled <-
image_scale(all_images_joined, "x90")
# Test whether a single file will be written or multiple files;
# only writes one file (even if I
for (i in 1:length(all_images_scaled)) {
image_write(all_images_scaled[[i]], path = "filepath/new_cropimages/filename")
}
理想情况下,我会使用 for 循环缩放图像。这样我就可以将缩放后的图像保存到一个目录中。这没有用——我没有收到错误,但是当我检查变量的内容时它是空的。 image_join 函数将它们放在一起并将高度缩放为 90(宽度也按比例缩放)但我无法将单独的图像写入目录。此外,下一部分是跨宽度裁剪每个图像并保存新图像文件-name_1.png,对于每个 90x90 图像,移动超过 90 像素,裁剪 90x90,依此类推。我选择 magic 是因为它很容易单独缩放和裁剪,但我对其他想法持开放态度(或学习如何使该包工作)。感谢您的帮助。
这是一些图片:
[Original Image, untransformed][1]
[Manual 90x90 crop][2]
[Another manual 90x90 crop, farther down the same image][3]
[1]: https://i.stack.imgur.com/8ptXv.png
[2]: https://i.stack.imgur.com/SF9pG.png
[3]: https://i.stack.imgur.com/NyKxS.png
我不会说 R,但我希望能够在 ImageMagick 方面提供帮助并处理 16,000 张图像。
当你在 Mac 上时,你可以使用 homebrew 非常轻松地安装 2 个非常有用的包,使用:
brew install imagemagick
brew install parallel
所以,您的原始句子图像是 1850x105 像素,您可以在终端中看到这样的图像:
magick identify sentence.png
sentence.png PNG 1850x105 1850x105+0+0 8-bit Gray 256c 51626B 0.000u 0:00.000
如果将高度调整为 90px,宽度按比例调整,它将变为 1586x90px:
magick sentence.png -resize x90 info:
sentence.png PNG 1586x90 1586x90+0+0 8-bit Gray 51626B 0.060u 0:00.006
因此,如果您调整大小然后裁剪成 90 像素宽的块:
magick sentence.png -resize x90 -crop 90x chunk-%03d.png
你将得到 18 个块,除最后一个外,每个块宽 90 像素,如下所示:
-rw-r--r-- 1 mark staff 5648 6 Jun 08:07 chunk-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:07 chunk-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:07 chunk-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:07 chunk-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:07 chunk-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:07 chunk-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:07 chunk-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:07 chunk-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:07 chunk-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:07 chunk-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:07 chunk-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:07 chunk-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:07 chunk-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:07 chunk-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:07 chunk-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:07 chunk-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:07 chunk-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:07 chunk-017.png
现在,如果您有 16,000 个句子要处理,您可以使用 GNU Parallel 并行完成它们,并为所有文件获取合理的名称。让我们先做一个 dry-run 所以它实际上什么都不做,只是告诉你它会做什么:
parallel --dry-run magick {} -resize x90 -crop 90x {.}-%03d.png ::: sentence*
示例输出
magick sentence1.png -resize x90 -crop 90x sentence1-%03d.png
magick sentence2.png -resize x90 -crop 90x sentence2-%03d.png
magick sentence3.png -resize x90 -crop 90x sentence3-%03d.png
这看起来不错,所以删除 --dry-run
并再次执行,对于我所做的三个(相同副本)句子,您将得到以下输出:
-rw-r--r-- 1 mark staff 5648 6 Jun 08:13 sentence1-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:13 sentence1-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:13 sentence1-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:13 sentence1-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:13 sentence1-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:13 sentence1-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:13 sentence1-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:13 sentence1-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:13 sentence1-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:13 sentence1-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:13 sentence1-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:13 sentence1-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:13 sentence1-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:13 sentence1-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:13 sentence1-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:13 sentence1-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:13 sentence1-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:13 sentence1-017.png
-rw-r--r-- 1 mark staff 5648 6 Jun 08:13 sentence2-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:13 sentence2-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:13 sentence2-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:13 sentence2-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:13 sentence2-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:13 sentence2-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:13 sentence2-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:13 sentence2-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:13 sentence2-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:13 sentence2-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:13 sentence2-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:13 sentence2-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:13 sentence2-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:13 sentence2-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:13 sentence2-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:13 sentence2-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:13 sentence2-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:13 sentence2-017.png
-rw-r--r-- 1 mark staff 5648 6 Jun 08:13 sentence3-000.png
-rw-r--r-- 1 mark staff 5319 6 Jun 08:13 sentence3-001.png
-rw-r--r-- 1 mark staff 5870 6 Jun 08:13 sentence3-002.png
-rw-r--r-- 1 mark staff 6164 6 Jun 08:13 sentence3-003.png
-rw-r--r-- 1 mark staff 5001 6 Jun 08:13 sentence3-004.png
-rw-r--r-- 1 mark staff 6420 6 Jun 08:13 sentence3-005.png
-rw-r--r-- 1 mark staff 4726 6 Jun 08:13 sentence3-006.png
-rw-r--r-- 1 mark staff 5559 6 Jun 08:13 sentence3-007.png
-rw-r--r-- 1 mark staff 5053 6 Jun 08:13 sentence3-008.png
-rw-r--r-- 1 mark staff 4413 6 Jun 08:13 sentence3-009.png
-rw-r--r-- 1 mark staff 5960 6 Jun 08:13 sentence3-010.png
-rw-r--r-- 1 mark staff 5392 6 Jun 08:13 sentence3-011.png
-rw-r--r-- 1 mark staff 4280 6 Jun 08:13 sentence3-012.png
-rw-r--r-- 1 mark staff 5681 6 Jun 08:13 sentence3-013.png
-rw-r--r-- 1 mark staff 5395 6 Jun 08:13 sentence3-014.png
-rw-r--r-- 1 mark staff 5065 6 Jun 08:13 sentence3-015.png
-rw-r--r-- 1 mark staff 6322 6 Jun 08:13 sentence3-016.png
-rw-r--r-- 1 mark staff 4848 6 Jun 08:13 sentence3-017.png
关于parallel
参数的解释:
{}
指的是"the current file"{.}
指的是"the current file without its extension":::
将用于parallel
的参数与用于magick
命令的参数分开
请注意,PNG 图像可以 "remember" 它们的来源可能有用,也可能非常烦人。如果你从上面看最后一个块,你会看到它是 56x90,但紧随其后的是 "remembers" 它来自 canvas 1586x90,偏移量为 1530 ,0:
identify sentence3-017.png
sentence3-017.png PNG 56x90 1586x90+1530+0 8-bit Gray 256c 4848B 0.000u 0:00.000
这有时会打乱令人讨厌的后续处理,或者有时在 re-assembling 被切碎的图像中非常有用!如果要去掉,需要重新分页,所以上面的命令就变成了:
magick input.png -resize x90 -crop 90x +repage output.png
已更新 - 更好地利用 EBImage 中的工具
ImageMagick 是一个很好的方法。但是如果您想对图像执行一些内容分析,这里有一个使用 R 的解决方案。R 确实提供了一些非常方便的工具。此外,图像只是矩阵,R 处理得很好。通过将图像缩减为矩阵,包 EBImage
做得很好,并且无论好坏,都删除了每个图像的一些元数据。这是 EBImage
的 R 解决方案。不过,Mark 的解决方案可能更适合真正的大批量生产。
解决方案是围绕一个大的“for”循环构建的。在几个步骤中添加错误检查是明智的。该代码利用 EBImage
来管理彩色和灰度图像。
在这里,通过添加所需背景颜色的像素,最终图像在扩展图像中居中。然后将扩展图像裁剪成图块。如果需要,可以调整确定 pad
值的逻辑以简单地裁剪图像或左对齐或右对齐。
首先假设您从工作目录开始,源文件在 ./source
中,目标文件在 ./dest
中。它还为每个“平铺”图像创建一个新目录。这可以更改为让一个目录接收所有图像以及其他保护编码。此处,假定图像是具有适当扩展名的 PNG 文件。要应用于高度和宽度的所需图块大小 (90) 存储在变量 size
.
# EBImage needs to be available
if (!require(EBImage)) {
source("https://bioconductor.org/biocLite.R")
biocLite("EBImage")
library(EBImage)
}
# From the working directory, select image files
size <- 90
bg.col <- "transparent" # or any other color specification for R
ff <- list.files("source", full = TRUE,
pattern = "png$", ignore.case = TRUE)
# Walk through all files with a 'for' loop,
for (f in ff) {
# Extract base name, even names like "foo.bar.1.png"
txt <- unlist(strsplit(basename(f), ".", fixed = TRUE))
len <- length(txt)
base <- ifelse(len == 1, txt[1], paste(txt[-len], collapse = "."))
# Read one image and resize
img <- readImage(f)
img <- resize(img, h = size) # options allow for antialiasing
# Determine number tiles and padding needed
nx <- ceiling(dim(img)[1]/size)
newdm <- c(nx * size, size) # extend final image
pad <- newdm[1] - dim(img)[1] # pixels needed to extend
# Translate the image with given background fille
img <- translate(img, c(pad%/%2, 0), output.dim = newdm, bg.col = bg.col)
# Split image into appropriate sized tiles with 'untile'
img <- untile(img, c(nx, 1), lwd = 0) # see the help file
# Create a new directory for each image
dpath <- file.path("dest", trimws(base)) # Windows doesn't like " "
if (!dir.create(dpath))
stop("unable to create directory: ", dpath)
# Create new image file names for each frame
fn <- sprintf("%s_%03d.png", base, seq_len(nx))
fpaths <- file.path(dpath, fn)
# Save individual tiles (as PNG) and names of saved files
saved <- mapply(writeImage, x = getFrames(img, type = "render"),
files = fpaths)
# Check on the results from 'mapply'
print(saved)
}