Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(bug) Image uploads are rescaled to 2000x2000, even if source image is smaller #1101

Closed
Tracked by #1473
HeyItsLollie opened this issue Aug 4, 2023 · 25 comments
Closed
Tracked by #1473
Labels
feature-request A request for a new feature

Comments

@HeyItsLollie
Copy link

HeyItsLollie commented Aug 4, 2023

Bluesky appears to rescale images to fit a maximum resolution of 2000x2000 pixels. While this step is understandable for handling larger images, it makes no sense to perform this on smaller images.

This also likely means that file size does not appear to be a factor in whether an image is processed and recompressed. Images are simply made to fit 2000x2000 indiscriminately. If these images are being stored at this resolution, they'd be wasting more server space and network bandwidth than necessary in the process.

I've noticed this with my own images posted via PC (Win 11, Firefox), and also in many images uploaded by other users.

Ideally, if an image is smaller than the max resolution or file size, simply leave it be. Additionally, the front-end should state the max resolution and file size somewhere, so that users can better prepare their images for the platform if they have the means.

@HeyItsLollie HeyItsLollie added the feature-request A request for a new feature label Aug 4, 2023
@Zero3K
Copy link

Zero3K commented Aug 4, 2023

I saved an image from Bluesky and can see that the size is almost 2000x2000 (but the file size is only 231 KB) This really needs to be fixed ASAP.

@HeyItsLollie
Copy link
Author

I've accidentally submitted this issue with the "feature request" label - this was intended to be a bug report, sorry.

One behavior that leaves me puzzled: image URLs include the line "\rs:fit:2000:2000:1:0", leaving me to believe that this scaling might actually be performed when delivering it to a user, and not on upload as I originally assumed. But I don't understand why this step would even be necessary. Browsers have long supported arbitrary scaling of images, and it's a common feature of any modern graphics rendering library. What does this step actually achieve?

@HeyItsLollie HeyItsLollie changed the title Image uploads are rescaled to 2000x2000, even if source image is smaller (bug) Image uploads are rescaled to 2000x2000, even if source image is smaller Aug 8, 2023
@pfrazee
Copy link
Collaborator

pfrazee commented Aug 10, 2023

I think is a question for @devinivy, I'm not sure what the backend logic is and I'm 75% sure we don't scale up in the client

@devinivy
Copy link
Contributor

That's right, images are resized on demand and then cached. So if the original image in a user's repository is very large, we can still serve a resized, compressed, jpeg version of it to the client as e.g. their avatar which is generally displayed much smaller. The next time another user asks for the same avatar image, they will be served the cached version. Especially in the federated setting where the originals could be varied in size/format/etc, this ensures clients are getting consistent views of images on the network.

We'll take a look into the upscaling issue 👍

@HeyItsLollie
Copy link
Author

So if the original image in a user's repository is very large, we can still serve a resized, compressed, jpeg version of it to the client as e.g. their avatar which is generally displayed much smaller.

So one big problem with the current approach is that the resized/recompressed JPG is being served regardless of whether that version is actually smaller than the original image. PNGs can be considerably smaller in filesize compared to JPGs, and this format is commonly used in art spaces — especially true for pixel art.

As a quick example, here's a random screenshot from an old PC-98 game. 640×400, a mere 22kb.
angel-halo_19

After Bluesky resizes and compresses it, the image becomes 408kb, an 18× increase.
explorer - 2023-08-15 - 09-16-35

Even if this is only resized and cached on demand, the version that ends up being delivered is unnecessarily bloated, compared to the original. This is where it'd make the most sense to cache and deliver the original instead (with certain metadata stripped).

@Zero3K
Copy link

Zero3K commented Dec 27, 2023

This bug hasn't been fixed yet.

@Tuss36
Copy link

Tuss36 commented Feb 7, 2024

I too am greatly vexed by this. Especially for jpeg works, as it makes the jpeging around the edges much more noticeable, though it's also especially bothersome for creators that post things at particularly small resolutions.

@qazmlp
Copy link

qazmlp commented Sep 12, 2024

Adding another example here: https://bsky.app/profile/qazm.bsky.social/post/3l3yad77cag2s

A post with "A very low-res pixel rendering of a stylised goat face." which looks supremely awful.

The original is a 1.04 KB PNG, the CDN version is a 70.5 KB JPEG.

Please consider using image-rendering: pixelated; for very-low-res content too, or better yet adding the option to prefer pixel scaling for display during upload of low-res media.

@gaearon
Copy link
Collaborator

gaearon commented Sep 13, 2024

Does anyone know whether upscaling is done by the client or at a later stage? I.e. are the originals on PDS correct or is the client borking it.

@qazmlp
Copy link

qazmlp commented Sep 13, 2024

Does anyone know whether upscaling is done by the client or at a later stage? I.e. are the originals on PDS correct or is the client borking it.

https://atproto-browser.vercel.app/at/did:plc:2shmwstgqmlu4ymg7ctjcdc7/app.bsky.feed.post/3l3yad77cag2s says the blob content size for my image is 2113 [bytes?] and the dimensions are 32x32, so that's fine(-ish. Would be better/smaller if it was still a PNG, but it shouldn't fully skip the reencode when uploading so that meta data is still stripped).

I'm pretty sure it's mainly the CDN that's causing issues here, but the client should receive a patch to display low-res images better, too.

@mistydemeo
Copy link

Just wanted to chime in to say that this is very noticeable on one of my accounts, which primarily posts computer screenshots at 640x480 and smaller. For example, this 512x384 image really didn't need to get scaled up: https://bsky.app/profile/cd-i.bsky.social/post/3l43jrdmk2p2r

The filesize was also bloated: the original 512x384 PNG is 24KB, but the upscaled 2000x1500 JPG is 205KB.

@ds84182
Copy link

ds84182 commented Sep 14, 2024

Maybe the client should skip the CDN and use the blob directly if the blob size is known to be small. If the aspect ratio for embedded images is guaranteed to equal the size of the original image this would be rather easy to implement. Otherwise reading file headers (for PNG) or SOF (for JPEG) would give the original image size without having to download all of it.

@qazmlp
Copy link

qazmlp commented Sep 15, 2024

Maybe the client should skip the CDN and use the blob directly if the blob size is known to be small. If the aspect ratio for embedded images is guaranteed to equal the size of the original image this would be rather easy to implement. Otherwise reading file headers (for PNG) or SOF (for JPEG) would give the original image size without having to download all of it.

Can't be done this way. That's a deanonymisation vector.
(That's why email clients mostly don't load external images by default and why Google unconditionally loads all external images in mails sent to Gmail addresses into their CDN, whether the address actually exists or not.)

It doesn't matter anyway though, as both the CDN and client are controlled by Bluesky, so they can fix the CDN here (which would also reduce load on their hosting infrastructure).

@mistydemeo
Copy link

If it's a CDN-side issue - is the CDN open-source or closed-source? Is there somewhere this issue should be filed to be more actionable?

@ds84182
Copy link

ds84182 commented Sep 30, 2024

If it's a CDN-side issue - is the CDN open-source or closed-source? Is there somewhere this issue should be filed to be more actionable?

@mistydemeo I couldn't find references to the CDN anywhere, so it seems like its closed source.

That's right, images are resized on demand and then cached. So if the original image in a user's repository is very large, we can still serve a resized, compressed, jpeg version of it to the client as e.g. their avatar which is generally displayed much smaller. The next time another user asks for the same avatar image, they will be served the cached version. Especially in the federated setting where the originals could be varied in size/format/etc, this ensures clients are getting consistent views of images on the network.

We'll take a look into the upscaling issue 👍

@devinivy is this still on your radar? I know it seems like a fairly small issue but the upscaling also impacts downloading images in the app. They're much larger than they need to be.

@woot000
Copy link

woot000 commented Oct 2, 2024

The images being upscaled appear to also give them very pronounced ringing, which looks absolutely hideous for stuff like pixel art and web screenshots. This really should be dealt with as soon as possible, this issue makes images uploaded to Bluesky lower quality across the board

@devinivy
Copy link
Contributor

devinivy commented Oct 2, 2024

Yes, totally hearing yall 👍 It remains on our radar and we intend to patch it up soon. As mentioned above, it is a bsky CDN issue and the path to fixing it up looks clear.

@qazmlp
Copy link

qazmlp commented Oct 3, 2024

Once this is fixed, would you consider (slowly, if necessary) invalidating the cache for older images too?

@sanitybit
Copy link

@ds84182 The CDN being used by Bluesky is currently imageproxy.

@devinivy
Copy link
Contributor

This should finally be resolved! https://bsky.app/profile/divy.zone/post/3l6ipmrzso42b

Newly-posted images will get the fix immediately, and old images will gradually (within days) fall out of the cache and be replaced with new versions.

@mistydemeo
Copy link

mistydemeo commented Oct 14, 2024

Confirmed! https://bsky.app/profile/cdrom.ca/post/3l6ipu6q6vh2r Thank you very much!

It looks like the other half of the issue is still here though: the source image for that post is a 6KB PNG, but it was recompressed into a 137KB JPEG.

scummvm-choroli-mac-ja-00001

@HeyItsLollie
Copy link
Author

Good to see the resolution part of this issue is finally resolved, very happy to see it. Would be great to see file-size be accounted for as well, especially for instances like the case above - unnecessary conversion of PNGs to JPGs when the the former is far smaller than the latter.

@qazmlp
Copy link

qazmlp commented Oct 17, 2024

Probably not super important, but the effective quality for tiny images got worse 😰

before after
image image

(Still slightly larger than the original PNG, but not by much.)

It would be great if Bluesky supported pixel icon art without having to scale it up at some point.
That needs both a fix here and conditional image-rendering: pixelated in the client, though.

@gaearon
Copy link
Collaborator

gaearon commented Nov 4, 2024

Seems like the remaining issue is JPG -> PNG conversion, let's track that in #5855.

@gaearon gaearon closed this as completed Nov 4, 2024
@theblackhole
Copy link

Seems like the remaining issue is JPG -> PNG conversion, let's track that in #5855.

There's also the fact that Bluesky still scale up images (client-side) and doesn't do well with pixel art (see previous comment #1101 (comment))
Maybe a new issue should be created for that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A request for a new feature
Projects
None yet
Development

No branches or pull requests