I need to automate some image transformations to do the following: - read in 16,000+ images that are short and wide, sizing is not the same. - rescale each image to 90 pixels high - crop 90 pixels over the width of the image, so multiple 90x90 crops over 1 image - then do it all over again for the next image - each 90x90 image needs to be saved as file-name_1.png, file-name_2.png and so on in sequential order
I've completed a test on 8 images, and using the magick package I was able to rescale and create multiple crops from each image manually. The problem is when I try to do multiple, I am able to resize the images easily but when it comes to saving them there is a problem.
# 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")
}
Ideally, I would scale the images with a for loop. That way I can save the scaled images to a directory. This didn't work - I don't get an error, but when I check the contents of the variable it is null. The image_join function puts them all together and scales the height to 90 (width is also scaled proportionately) but I can't write the separate images to directory. Also, the next piece is to crop each image across the width and save the new images file-name_1.png, and so on for every image 90x90, move over 90 pixels, crop 90x90, and so on. I chose magic because it was easy to individually scale and crop, but I'm open to other ideas (or learning how to make that package work). Thanks for any help.
Here are some images:
[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
I don't speak R, but I hope to be able to help with the ImageMagick aspects and getting 16,000 images processed.
As you are on a Mac, you can install 2 very useful packages very easily with homebrew, using:
So, your original sentence image is 1850x105 pixels, you can see that in Terminal like this:
If you resize the height to 90px, leaving the width to follow proportionally, it will become 1586x90px:
So, if you resize and then crop into 90px wide chunks:
you will get 18 chunks, each 90 px wide except the last, as follows:
Now, if you have 16,000 sentences to process, you can use GNU Parallel to get them all done in parallel and also get sensible names for all the files. Let's do a dry-run first so it actually doesn't do anything, but just shows you what it would do:
Sample Output
That looks good, so remove the
--dry-runand do it again and you get the following output for the three (identical copies) of your sentence I made:A word of explanation about the parameters to
parallel:{}refers to "the current file"{.}refers to "the current file without its extension":::separates the parameters meant forparallelfrom those meant for yourmagickcommandOne note of warning, PNG images can "remember" where they came from which can be useful, or very annoying. If you look at the last chunk from above you will see it is 56x90, but that following that, it "remembers" it came from a canvas 1586x90 at offset 1530,0:
This can sometimes upset subsequent processing which is annoying, or sometimes be very useful in re-assembling images that have been chopped up! If you want to remove it, you need to repage, so the command above becomes: