lupinia / awi

Full Lupinia/Awi website, built with Django
https://www.lupinia.net/
2 stars 1 forks source link

Sunset: Control crop alignment for resized image assets #92

Open lupinia opened 1 year ago

lupinia commented 1 year ago

The current code to generate image assets for images centers the image before cropping. Which is a handy default, and was fine when the only images that were actually being cropped were page backgrounds. But since the Twitter/OG images also use the same method, the preview images used in these meta tags aren't always awesome.

Twitter itself had this problem for a while, and initially approached it the same way, always cropping to the center. It wasn't great, but it was standardized and predictable. Then they changed it to try to use facial recognition software to ensure that people's faces weren't getting cut off. It didn't go well. So they finally added a tool that provides granular control on a per-image basis, which has been adopted in a few other places (Mastodon has similar functionality).

I definitely do not have the JS skillz to pull off an interface like that, nor do I want or need anything of the sort - it's my web app for my images, and I'm both the developer and the admin, I don't need a fancy interface to correct for server-side limitations.

But, what I can do, and what I'd like to do in this issue, is add fields to sunset.image objects for horizontal and vertical alignment (horizontal alignment is pretty much never used right now, but I like data symmetry), which set the crop alignment for image resizes that get cropped. It would still be a manual process, which makes sense because I won't see whether it needs adjusting until after a new image has been imported and processed, but it should be fairly simple to adjust, at which point the resized assets will be generated in the background at the next cron job.

In theory, I could probably implement more granular controls numerically, similar to the back-end data of the Twitter/Mastodon center-point selection interface, but it's difficult to manage that without some sort of spiffy "click the image to choose its center point" widget, and I can't imagine a scenario where I would need that level of granularity.

lupinia commented 1 year ago

I think I spent more time writing about this feature than I spent implementing it, but this is now in place, via text-based options for left/center/right and top/center/bottom. It'll take time to go through the gallery and actually set this value on the images that need it - there are more than I thought - but the capability exists on a technical level now, and it works pretty well!

lupinia commented 1 year ago

Re-opening this because, while the new adjustment is definitely a significant improvement for most images that need it, it doesn't actually solve the problem for all of them.

So, here's the problem: Simple and blunt controls for just left, right, top, bottom, and center are extremely simple and easy to maintain. Something like a social media app expects a high volume of users that are each posting a low volume of images, while I'm optimizing for a low volume of users (just one) posting a high volume of images. So, I need the controls to be easy to maintain at the data model level. But, how do I do that beyond the current options?

I'm going to give this some thought before proceeding further. The most pressing question is, exactly how much precision do I need? At the moment, on a scale of 0 to 1, the precision is 0.5, or 50%, and that's not good enough, but also don't need or want infinite precision, or even 1% precision. Especially since I'll basically be eyeballing the setting without knowing in advance what it'll look like, and the actual resizing takes place asynchronously. The next step would probably be 25%, but I need to take a good look at the images that need work to see if that would help. The greatest precision I'm willing to even consider is 10% (increments of 0.1), which would probably allow for near-perfect alignment of every single link preview image ever, but I'm not sure I can accurately anticipate what the value should be. Annoyingly, it's difficult to do 20% or 33% because 50% (center) must be an option, plus it's difficult to define an interface for steps other than 25% or 50% without just making it directly numeric, and at that point I might as well just make the step precision 10%.

lupinia commented 1 year ago

Upon further reflection, it would be pretty easy to adapt the current implementation/interface for 25% precision, by just adding intermediate values to the existing scale (left/center-left/center/center-right/right or top/center-top/center/center-bottom/bottom) and expanding the field to 2 characters instead of just one.

lupinia commented 1 year ago

I went through the images that needed crop adjustments, trying to use the new 25% settings, and while I haven't done a full review of all of them yet, I've already spotted a couple where this setting is clearly not solving anything. And I've found an additional problem: As this setting gets more precise, there's an increased likelihood of having a setting that works for the link-preview images but doesn't work at all for the page background, or vice-versa. I'm not entirely sure what to do about that yet.

At this point, I don't think there's any way around having some sort of direct-entry field for this, but I don't want to always have to enter a specific number. The exact next steps I take will depend somewhat on how many images still need to be fixed after the last round of adjustments, but I'm leaning toward keeping the existing fields as-is, and then adding a manual override field. That way, I can get a quick and intuitive adjustment to work with, and if that doesn't work for a particular image, I can enter an exact number by hand. Alternately, if most or all of the images that needed more than 50% precision also turn out to need more than 25% precision, I might just give up on the current fields entirely and replace them with a percentage field with a drop-down selector at 10% increments.

lupinia commented 1 year ago

There may be no way to get around having some sort of JS widget as the interface for this, but I'm starting to feel more confident in doing so. The workflow would be something like this:

  1. Click a "crop" button in the admin toolbar when viewing the image. This replaces the "crop" button with a "cancel" button.
  2. An overlay box appears over the image, with relative proportions corresponding to the OpenGraph image dimensions.
  3. Arrow buttons appear, which adjust the center point in 10% (0.1) increments. Along with a "reset" button that moves back to 0.5, 0.5
  4. As the adjustment is made, the position of the overlay box updates in real time.
  5. If the crop center values have changed, a "save" button appears. If clicked, it saves the changes, and marks the image for reprocessing.

Of these steps, the hardest-sounding part is step 2, due to the math involved. Also, while I did some work on the new tab page in just plain JS, this may be a situation where jQuery makes the most sense.