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

Add BlurHash encoding #20

Closed
cachapa opened this issue May 19, 2020 · 12 comments
Closed

Add BlurHash encoding #20

cachapa opened this issue May 19, 2020 · 12 comments

Comments

@cachapa
Copy link

cachapa commented May 19, 2020

There are some use-cases where it is useful to perform encoding on the device, e.g. when sending large images using e2e encryption.

Adding encoding to this package would support that use case without including another dependency. I'm not too familiar with the BlurHash algorithm but I suspect this wouldn't add much code to the implementation.

For reference, here's the blurhash_dart implementation, which itself has no dependencies: https://github.com/justacid/blurhash-dart/blob/master/lib/src/blurhash.dart#L70

@SaadArdati
Copy link

This is exactly what I was looking for! Haha

I needed a server-side BlurHash encoder with no dependencies.

@Solido
Copy link
Member

Solido commented May 24, 2020

Use case is way too marginal to add it as a Flutter package.

In e2e you're still using a central server which is by far a better solution as you can rely on the C implementation.

Thanks !

@Solido Solido closed this as completed May 24, 2020
@cachapa
Copy link
Author

cachapa commented May 24, 2020

In e2e encrypted communication the server doesn't have access to the image in order to encode it though. That's the whole point of e2e, or am I misunderstanding your comment?

@Solido
Copy link
Member

Solido commented May 24, 2020

You're totally right !
but it still can figure out the use case in e2e.

Original file on mobile 1 -> encryption -> decryption on mobile 2 using p2p or central server.

How does blurhash help in this ? the time to generate the blurshash is equivalent to encryption.

While would you send the hash at the same time than the real file ?

@cachapa
Copy link
Author

cachapa commented May 24, 2020

For example, sending an image from device1 to device2:

  1. device1 takes a photo
  2. device1 computes the blurhash
  3. device1 composes a json payload which includes the blurhash and sends it to device 2
  4. device1 starts sending the photo to device2
  5. device2 gets the payload and displays a blurhash placeholder
  6. device2 replaces the placeholder with the photo once it's downloaded

To be clear, I understand your reasoning that this may not be common enough to make sense implementing in your package. My only argument against that is that it wouldn't be a huge amount of code, but I also understand not wanting to maintain it.

@Solido
Copy link
Member

Solido commented May 24, 2020

Encoding to blurhash is an expensive method that's why low level C is still preferred with batch encoding of already available content.

Encoding an image in a mobile device to send the hash before the real image will not make a huge gain.

If more use cases scenarii emerge then I'll consider the option.

Thanks @cachapa

@cachapa
Copy link
Author

cachapa commented May 24, 2020

Encoding to blurhash is an expensive method that's why low level C is still preferred with batch encoding of already available content.

Actually it's pretty fast (< 100 ms) provided you resize the image before encoding (which is also recommended by the official implementation).

Encoding an image in a mobile device to send the hash before the real image will not make a huge gain.

I don't understand this argument. Isn't the entire reason for BlurHash to show placeholders while images download? Mobile devices sometimes have pretty bad network so even a relatively small photo can take a while to download.

@Solido
Copy link
Member

Solido commented May 24, 2020

Yes but how much for resizing in mobile ? you need to load the image in memory, resize it then encode for the hash then you send the hash. At the same time you also need to encrypt the image.

On the second case you just encrypt the image and send it.

The whole use case of blurhash is having instant display that's why you batch the encoding with efficient process. Mainly C in mass parallel batch. Then you send the link to the image which name is the hash. Here you have instant display. The image is not encoded when you request it, it has been prepared upfront.

In your case the image is not ready when you ask for it so you add the hash encoding and on top of that the encryption.

Do you want this for a chat app where someone is not asking for an image but waiting that an undefined resource is hashed and encrypted.
Then the whole process would be much more effective with native bridge than using encoding in Flutter.

@cachapa
Copy link
Author

cachapa commented May 24, 2020

Resizing images is actually quite efficient on mobile since it uses the GPU which is optimized for exactly that - every time you display an image on the device it's being implicitly resized to the size of its view.

In fact, the slowest part is reading the bytes but that's a price you have to pay anyway in order to encrypt and send the data.

I agree that the point of blurhash is to have an instant display, which is why I'm confused about you saying it doesn't make sense for a chat app.
I'm also confused by what you mean with "mass parallel batch". We're talking about sending a single picture to another user.

What I'm talking about isn't hypothetical: WhatsApp uses e2e encryption and shows a blurred placeholder when receiving images.

@Solido
Copy link
Member

Solido commented May 24, 2020

Ok I put imaginary numbers so we can clarify

Loading image i1 in memory : 200ms

  • BlushHash i1 : 100ms
    // Since we're in dart you can't encode image in a different isolate so ... you wait !
  • Sending blushHash
  • Encrypting i1 : 300ms
  • Send encrypted image

What's the gain here ? 200ms between the two messages and you send the same information twice. Also it's still with a central server so at scale it cost you network fees.
It's obviously a badly designed architecture for latency and running cost.

What I suspect they do in real world chat is they ONLY send the encrypted content then you decrypt in and calculate a blur effect from decoded data. It's much more efficient.

I get your point you don't get mine. BlurHash is useless in a chat it's used only as aesthetics when it's vital in a landing page when resources are pre-encoded for perception of loading speed.

This use case is not the blurhash use case when let's say Medium receive images for an articles they encode the image by batch because you simply won't start a process for each img, you do that at scale for cost and then replace the link in the article with the hash as link.

Feel free to test other libs to encode image as blurhash and send two messages to the channel for each posted image to see how effective it's.

@cachapa
Copy link
Author

cachapa commented May 24, 2020

No need for imaginary numbers, I already have it implemented and on my phone it takes between 50 and 150 ms to generate a blurhash of high resolution images.

It's obviously a badly designed architecture for latency and running cost.

Sorry but I find this incredibly condescending and arrogant. You know nothing about my product or architecture yet feel entitled to comment on the quality of its design?

What I suspect they do in real world chat is they ONLY send the encrypted content then you decrypt in and calculate a blur effect from decoded data. It's much more efficient.

You suspect wrong. You can verify this by disabling automatic image download. Signal actually uses BlurHash for the same purpose btw, so there are at least two successful products that agree with the use-case.
I mean, why would you calculate the blur effect if you already have the image? That doesn't make any sense.

I'm honestly surprised at your resistance to this, especially considering you're the maintainer of a BlurHash package. You say it's only used as aesthetics as if making beautiful products that people like to use was a bad thing.
I'm also surprised you speak to the BlurHash use case as if it was only useful for Medium-style large-scale deployments, when the original developers specifically say they were motivated to work on it because loading images on mobile devices is sometimes too slow.

To be clear I managed to make my implementation work using only blurhash-dart so I was just continuing this discussion out of academic curiosity.

@Solido
Copy link
Member

Solido commented May 25, 2020

Sorry that you think I'm arrogant and that you feel judged on your choice.

I think you still miss my point about when using BlurHash or not.

If you architecture works for you it's the more important yet I'm convinced I would never do that in an architecture for chat.

You makes me tell stuff I don't said. BlurHash should be used when expectation of speed is required like landing page or cold start. When in a chat, there's no such expectation and thus implementing it is not necessary. The receiving user never had the perception of a delay. That's my point.

Thanks for sharing your points

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants