Skip to content

Instantly share code, notes, and snippets.

@brenogazzola
Last active October 10, 2024 11:16
Show Gist options
  • Save brenogazzola/a4369965a1da426d50f11d080fe2e563 to your computer and use it in GitHub Desktop.
Save brenogazzola/a4369965a1da426d50f11d080fe2e563 to your computer and use it in GitHub Desktop.
Steps to migrate ImageMagick to Libvips

For apps built before the image_processing gem became the default, the migration will involve two steps:

  1. Migrating to the image processing syntax while still using ImageMagick;
  2. Switching to Vips and updating the compression options;

Migrate to the image processing syntax

Before changing from ImageMagick to Vips, it's better to first test the new syntax and ensure everything is still working.

1. Move everything that has to do with compression to a saver hash:

variant(format: :jpg, strip: true, quality: 80)
variant(format: :jpg, saver: { strip: true, quality: 80 })

If you forget to do this, when you switch to vips you will see this error: VipsOperation: class "quality" not found.

2. Change resize to resize_to_limit and switch from string to array:

variant(resize: "750x")
variant(resize_to_limit: [750, nil])

If you forget to do this, when you switch to vips you will see this error: no implicit conversion to float from string

3. Change crop from a string to an array and invert the position/dimension parameter:

variant(crop: "535x642+3+276")
variant(crop: [3, 276, 535, 642])

If you forget to do this, when you switch to vips you will see this error: unable to call crop: you supplied 2 arguments, but operation needs 5.

4. Clamp your crop values:

Vips is a more strict than ImageMagick when it comes to cropping:

  1. It will not crop if x and/or y are negative values. e.g.: [-10, -10, 100, 100]
  2. It will not crop if position (x or y) plus crop dimension (width, height) are larger than image dimensions. e.g.: a 125x125 image and a crop of [50, 50, 100, 100]

If you forget to do this, when you switch to vips you will see this error: extract_area: bad extract area

5. Adjust the background color used in resize and pad

Vips uses black as the default background color resize_and_pad, instead of white like ImageMagick. Fix that by using the background option:

variant(resize_and_pad: [300, 300])
variant(resize_and_pad: [300, 300, background: [255]])

Switch the variant processor

After you are sure everything is still working, switch the variant processor to vips, and make the following adjustments

1. Use the new compression options

Vips has different compression options compared to ImageMagick. This is a rough equivalent that you can use to update yours

# JPEG
variant(strip: true, quality: 80, interlace: "JPEG", sampling_factor: "4:2:0", colorspace: "sRGB")
variant(saver: { strip: true, quality: 80, interlace: true })

# PNG
variant(strip: true, quality: 75)
variant(saver: { strip: true, compression: 9 })

# WEBP
variant(strip: true, quality: 75, define: { webp: { lossless: false, alpha_quality: 85, thread_level: 1 } })
variant(saver: { strip: true, quality: 75, lossless: false, alpha_q: 85, reduction_effort: 6, smart_subsample: true })

# GIF
variant(layers: "Optimize")
variant(saver: { optimize_gif_frames: true, optimize_gif_transparency: true })

2. Remove any EXIF based rotation

Vips will auto rotate images using the EXIF value when processing variants. If you were storing rotation values from user uploaded photos to apply rotation with ImageMagick, you must stop doing that:

variant(format: :jpg, rotate: rotation_value)
variant(format: :jpg)

3: Change monochrome

Vips uses another options for black and white images

variant(monochrome: true)
variant(colourspace: "b-w")

After sending to production

If you are using fragment caching, make sure you clear your caches when you send vips to production. The urls generated by Active Storage contain an encoded value that represents the transformations that should be performed on the image and they will be in the old format. If you don't clear the caches you will start seeing the errors I mentioned above.

Finally, be prepared to STILL see some of those errors showing up as things outside of your control try to access old image urls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment