logo

Eugene's Space

Using imagemagick imagemagick emoji to crop soy faces

I’m pretty sure everyone knows that sometimes finding a good PNG can be very hard, while there’s always a bunch of the same JPEG images with the white background. After searching for 10 minutes, you decide to remove background yourself - using GIMP or something like Photoshop or PAINT.NET if you are on Windows. Forget about it! I’m gonna show you how you can use imagemagick to automate basic tasks like removing background and cropping images.

Telegram sticker pack

Every time I use Telegram stickers, I feel tired scrolling through many different packs trying to find the sticker I want. Sometimes, you just want them all to be in one place. That’s why I created Based Wojak - a sticker pack which is automatically generated from random source images that I find on the internet.

based-wojak

It doesn’t matter if the image has a white background or wrong resolution, I just put it in the src folder and then magic imagemagick emoji happens. For example, these are the source images used to generate the stickers above:

based-wojak-sources

The collection itself is very small right now as you can see, but I plan to extend it as I need more stickers. Add this pack:

https://t.me/addstickers/BasedWojak

Imagemagick

Now, let’s see how I’ve done that. Here’s the GitHub github emoji repo so you can follow:

https://github.com/eug-vs/telegram-based-wojak

You know, I love Makefiles. I use them everywhere (where they’re appropriate), even this website is generated by a Makefile. Let’s have a look at the Makefile for telegram-based-wojak:

# Makefile
SOURCES=$(wildcard src/*)
OUTPUTS=$(patsubst src/%.png, out/%.png, $(patsubst src/%.jpg, out/%.png, $(SOURCES)))

SIZE=512x512
FUZZ=50%

VIEW_COMMAND=sxiv -t


all: $(OUTPUTS)

view: all
	$(VIEW_COMMAND) out

viewsrc:
	$(VIEW_COMMAND) src

out/%.png: src/%.*
	@mkdir -p out
	magick $< \
		-fuzz $(FUZZ) -fill none \
		-floodfill +0+0 white \
		-floodfill "+%[fx:w-1]+0" white \
		-trim +repage \
		-resize $(SIZE) $@

clean:
	rm -rf out

On the first two lines I just create variables for input and output images. Then I define the SIZE - Telegram expects sticker’s largest side to be 512px. The value of FUZZ determines the sensitivity of removing the background - I use 50%, but that’s just something you can play with.

Now let’s have a closer look at the recipe for creating out/%.png from src/%.*. I use magick on the input file (denoted by $<), then pass a whole bunch of parameters to it, and finally provide the output file ($@). If you are confused by $< and $@, check out Makefile cheatsheet.

imagemagick-logo

Removing the background

To remove background, I use -floodfill, here’s how imagemagick wiki describes it:

-floodfill {+-}x{+-}y color

Floodfill the image with color at the specified offset.

Flood fill starts from the given ‘seed point’ which is not gravity affected. Any color that matches within -fuzz color distance of the given color argument, connected to that ‘seed point’ will be replaced with the current -fill color.

I use it two times: one in the top-left corner and one in the top-right. Top-left corner pixel obviously has a coordinate +0+0. To get the X coordinate of right-most pixel I have to use this expression: +%[fx:w-1], Y coordinate stays at 0 of course. Since I already supplied -fuzz and -fill none, both operations will replace the white background with none, starting from two top corners of the image using the supplied fuzziness value.

Cropping the image

After we removed background, most of the time we can trim a lot of extra space so that our image size corresponds to its content. Simple -trim +repage does the trick.

Adjusting the size

All we have to do now is to make sure the sticker respects the size with -resize option. It will resize it in a way so it fits into 512x512 box without changing the aspect ratio (largest side will always be 512px).