esmBot icon indicating copy to clipboard operation
esmBot copied to clipboard

The remaining ImageMagick-based commands

Open TheEssem opened this issue 3 years ago • 33 comments

With release 1.8, most of the image commands in the bot have been ported over from ImageMagick/Magick++ to the libvips library. While this has already resulted in a significant performance increase with image processing (and the bot in general), not all commands have been ported, either due to confusion regarding how they would be implemented or because of bugs in libvips.

This issue is here to track those unported commands and the current status of porting them. The goal is to completely remove ImageMagick as a dependency from the bot, and as such none of the ports should use it in any way. Help with porting these over is greatly appreciated.

Commands

  • [x] circle (radial/rotational blur effect, unsuccessful attempts have been made using mapim function)
  • [x] explode (working prototype using static mapim image, would be better to generate it on-the-fly)
  • [ ] magik (probably doable with liblqr [the same library that ImageMagick uses], though performance is a concern; maybe worth looking into porting https://github.com/li-plus/seam-carving)
  • [x] scott (slightly working prototype using static mapim image, would be better to generate it on-the-fly, antialiasing issues)
  • [x] spin (libvips has a rotate command, however it works much differently and I haven't figured out how to make it use the middle of the image as a center point/axle yet)
  • [x] swirl (tried using mapim and various polar coordinate functions, unsuccessful so far)
  • [x] tile (easy to port, attempted removal but kept due to popular demand)
  • [x] wall (need to generate perspective transform and use mapim with it, attempted removal but kept due to popular demand)

TheEssem avatar Jun 28 '22 20:06 TheEssem

Here is a (messy) tarball of what I have so far with explode, spin, and swirl: https://cdn.discordapp.com/attachments/523946539505156128/991436149694398474/vipsproto.tar.zst

TheEssem avatar Jun 28 '22 20:06 TheEssem

Hello, I could have a stab at one of these if you could post sample before-after images of the desired effect, or point me at the imagemagick command line that you are trying to replicate.

jcupitt avatar Jun 29 '22 11:06 jcupitt

what's wrong with the tile command? was it hard to maintain or just worked poorly? was it useless or deprecated?

blulere avatar Jun 30 '22 21:06 blulere

Hello, I could have a stab at one of these if you could post sample before-after images of the desired effect, or point me at the imagemagick command line that you are trying to replicate.

@jcupitt Oh nice, thanks for stopping by! Spin, scott, and swirl (sources linked) seem to be the toughest ones at the moment. Here's an example input image:

n2UtdJe

Here are some example outputs for spin, scott, and swirl (images linked by command name). Feel free to pick which one to go after.

TheEssem avatar Jul 07 '22 00:07 TheEssem

what's wrong with the tile command? was it hard to maintain or just worked poorly? was it useless or deprecated?

@BlueBlueTeam Mostly a mix between the slash command limit and lack of usage compared to the other commands. Might still consider keeping it.

TheEssem avatar Jul 07 '22 00:07 TheEssem

I had a stab at swirl in python (should be easy to adapt to C++):

#!/usr/bin/python3

import math
import sys

import pyvips

original = pyvips.Image.new_from_file(sys.argv[1])

# stretch the image out so we have lots of spare edge pixels
image = original.gravity("centre",
                         original.width * 3,
                         original.height * 3,
                         extend="copy")

# this makes an image where pixel (0, 0) (at the top-left) has value [0, 0],
# and pixel (image.width, image.height) at the bottom-right has value
# [image.width, image.height]
index = pyvips.Image.xyz(image.width, image.height)

# move the origin to the centre, negative values up and left,
# positive down and right
centre = index - [image.width / 2, image.height / 2]

# to polar space, so each pixel is now distance and angle in degrees from the
# centre
polar = centre.polar()

# swap distance around so we have 1 in the centre and 0 at the edges of the
# original image size ... square, so we have a gentler twist at the edge
size = min(original.width, original.height) / 2
d = (1 - polar[0] / size) ** 2

# add to a so we swirl by 180 degrees in the centre and 0 at the edges
a = polar[1] + d * 180

# and back to rectangular coordinates again to make a set of vectors we can
# apply to the original image
distort = polar[0].bandjoin(a).rect() + [image.width / 2, image.height / 2]

# distort the image
interp = pyvips.Interpolate.new("bicubic")
distorted = image.mapim(distort, interpolate=interp)

# crop out the original again
image = distorted.crop(original.width, 
                       original.height,
                       original.width, 
                       original.height)

image.write_to_file(sys.argv[2])

With:

$ ./swirl2.py ~/pics/test.jpg x.jpg

I get:

x

Not an exact match for your sample output, but maybe close enough?

jcupitt avatar Jul 07 '22 15:07 jcupitt

Apologies for the long wait, but yeah, that should work! I've finally went ahead and ported the Python code and committed it here: a2493bcc0ab6d9925ce7a104c29d98c5cbb8195c

Thank you so much once again for helping out, libvips is great! :D

TheEssem avatar Sep 11 '22 07:09 TheEssem

The scott command has been ported over with a77dc5a, that's one more off the list.

TheEssem avatar Mar 10 '23 19:03 TheEssem

The explode command is done! d236179

TheEssem avatar Mar 11 '23 21:03 TheEssem

The tile command is done. 5c17eca

TheEssem avatar Apr 13 '23 20:04 TheEssem