Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Improve the thumbnail service to support compression and WEBP #630

Merged
merged 16 commits into from
Apr 12, 2022

Conversation

dhruvkb
Copy link
Member

@dhruvkb dhruvkb commented Apr 6, 2022

Fixes

Fixes #531 by @zackkrida

Description

This PR replaces willnorris/imageproxy with h2non/imaginary, a faster, more feature-rich and more highly-rated library for image manipulations over HTTP. This library allows us to compress thumbnails and reduce bytes.

Now, we can control the dimensions of the thumbnail and the amount of compression using env vars (while also allowing the URL query params full_size and compressed override the defaults if needed).

To spark joy, this PR adds API documentation for the thumbnail endpoints (both audio and video) with all query params documented.

Testing Instructions

  1. Check out the PR and fetch thumbnails for some audio/image files. They should load normally.
  2. Play with the full_size and compressed query params.
  • With full_size set to 'true', the image should be larger.
  • With full_size set to 'false', the image will be smaller.
  • Compression is by default set to the opposite of full_size, but can be overridden with the compressed param.

Stats

Here are some randomly sampled cases.

Full-size no-compression Full-size compression Thumbnail no-compression Thumbnail compression
307 kB 84.1 kB 223 kB 30.6 kB
385 kB 96.1 kB 279 kB 39.9 kB
387 kB 108 kB 278 kB 42.9 kB

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the default branch of the repository (main) or a parent feature branch.
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@dhruvkb dhruvkb added 🟩 priority: low Low priority and doesn't need to be rushed 🌟 goal: addition Addition of new feature 💻 aspect: code Concerns the software code in the repository labels Apr 6, 2022
@openverse-bot openverse-bot added this to In progress in Openverse PRs Apr 6, 2022
@dhruvkb dhruvkb marked this pull request as ready for review April 6, 2022 09:59
@dhruvkb dhruvkb requested a review from a team as a code owner April 6, 2022 09:59
@openverse-bot openverse-bot moved this from In progress to Needs review in Openverse PRs Apr 6, 2022
@sarayourfriend
Copy link
Contributor

This is such a great find Dhruv! I'm excited to review this tomorrow 🙂

@zackkrida
Copy link
Member

Really exciting and a significant change. Can't wait to investigate this more.

Copy link
Contributor

@AetherUnbound AetherUnbound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! It sees quite fast too, which is rad. There aren't any pngs in the sample data to test with, but the JPEGs all look good 🙂 I have a few comments about logging

api/catalog/api/docs/audio_docs.py Outdated Show resolved Hide resolved
api/catalog/api/serializers/media_serializers.py Outdated Show resolved Hide resolved
api/catalog/api/views/media_views.py Outdated Show resolved Hide resolved
api/catalog/api/views/media_views.py Show resolved Hide resolved
@zackkrida
Copy link
Member

I'll test this soon, just want to note that we make sure to manually visually diff a few thumbnails against their current, production counterparts, to check for noteworthy quality differences or any other issues.

The new library looks great! It would be an excellent enhancement to figure out how to serve webp images in the future.

@dhruvkb
Copy link
Member Author

dhruvkb commented Apr 8, 2022

@zackkrida the h2non/imaginary service is capable of converting images sent to it to webp as well, if we send a type param in the request. I'll run some tests with that and see if that can further cut down the size.

@dhruvkb
Copy link
Member Author

dhruvkb commented Apr 8, 2022

Some more stats:

Thumnail compressed Thumbnail compressed WEBP
30.5 kB 19.2 kB
29.0 kB 16.9 kB
36.4 kB 22.6 kB

With compression and WEBP, we can reduce the size even more than the already compressed thumbnails.

Comment on lines +216 to +217
if "webp" in accept_header:
params["type"] = "auto" # Use ``Accept`` header to determine output type.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This converts JPG and PNG to WEBP if the Accept header contains it. Otherwise the format stays as it is. This is to prevent issues with Safari which before Big Sur, preferentially requests PNG. JPG images become quite large if converted to PNG.

Copy link
Contributor

@sarayourfriend sarayourfriend left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good! Just a few things to clean up/short-cut requests. This is really awesome though.

docker-compose.yml Outdated Show resolved Hide resolved
api/catalog/api/views/media_views.py Outdated Show resolved Hide resolved
api/catalog/api/views/media_views.py Outdated Show resolved Hide resolved
api/catalog/api/views/media_views.py Outdated Show resolved Hide resolved
api/catalog/api/views/media_views.py Outdated Show resolved Hide resolved
dhruvkb and others added 2 commits April 11, 2022 13:51
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Copy link
Contributor

@sarayourfriend sarayourfriend left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Tested locally and it works great.

Along with the full_size test, can you add unit tests for the serializer and the validate method specifically?

api/test/media_integration.py Show resolved Hide resolved
Copy link
Contributor

@sarayourfriend sarayourfriend left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just curious about the release issue, whether we'll need to build an image ourselves from the latest code?

@dhruvkb
Copy link
Member Author

dhruvkb commented Apr 11, 2022

Just noting that the process of building and hosting a custom image is being worked out in a separate PR, #641.

Copy link
Contributor

@AetherUnbound AetherUnbound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making those logging changes! I hope you get a response soon on the build issue, but if nothing else it's good to know we have another option.

Openverse PRs automation moved this from Needs review to Reviewer approved Apr 12, 2022
* Define a workflow to build Docker image for imaginary

* Use custom imaginary image in Docker Compose
@dhruvkb dhruvkb changed the title Improve the thumbnail service to support compression Improve the thumbnail service to support compression and WEBP Apr 12, 2022
@dhruvkb dhruvkb merged commit 2d5779b into main Apr 12, 2022
Openverse PRs automation moved this from Reviewer approved to Merged! Apr 12, 2022
@dhruvkb dhruvkb deleted the compression branch April 12, 2022 20:58
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
💻 aspect: code Concerns the software code in the repository 🌟 goal: addition Addition of new feature 🟩 priority: low Low priority and doesn't need to be rushed
Projects
No open projects
Openverse PRs
  
Merged!
Development

Successfully merging this pull request may close these issues.

Image thumbnail improvements (dimensions, compression)
4 participants