-
Notifications
You must be signed in to change notification settings - Fork 401
MSC2448: Using BlurHash as a Placeholder for Matrix Media #2448
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
base: old_master
Are you sure you want to change the base?
Changes from all commits
8ba6071
f71535a
8adf2b2
56703fc
793107d
777c30c
b80822e
b240d92
1afad01
60773e4
df5b6d7
571ce2a
e885eae
4b83c51
b893c21
6e8eb59
3695ecf
842c2a0
3994010
616bc81
e0a7442
385be8a
708b756
b761b06
40d71ff
7f13184
1300a6e
2a02d2c
7ea82b4
f93d708
ed9ed5e
48c4d55
fba60db
c837c83
b3f1915
5b8c191
63d4966
676571f
a302197
594bcee
64116ae
9bd0ba6
e7e0fb7
1d954f0
9e981ba
75a4fa6
934b6d7
974d368
5668397
234877c
abf5283
754fa7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,377 @@ | ||
# MSC2448: Using BlurHash as a Placeholder for Matrix Media | ||
|
||
[BlurHash](https://blurha.sh) is a compact representation of a placeholder | ||
for an image (or a frame of video). Currently, in Matrix, clients must | ||
display a placeholder image in the message timeline while a piece of media is | ||
loading. Some clients, such as Element, simply display an empty space. | ||
|
||
While thumbnails exist to combat this to some degree, they still need to be | ||
downloaded from a homeserver, which is not instantaneous. | ||
|
||
Instead, a BlurHash can be sent inside events, which upon | ||
receipt other clients can render for a pretty media preview while the actual | ||
thumbnail downloads. They also do not contain any `"` characters, making them | ||
simple to stick inside existing JSON blobs. | ||
|
||
To be clear: A BlurHash does not replace a thumbnail - rather it is a placeholder | ||
and should be shown before the thumbnail is downloaded. For a familiar messaging | ||
user experience, clients are recommended to first render and display a blurhash, | ||
then download the thumbnail of the media. Once the thumbnail file is downloaded, | ||
display it. Finally, the user can optionally view the full media item by selecting it. | ||
|
||
## Proposal | ||
|
||
### m.room.message | ||
|
||
An optional field is added in `m.room.message`'s `content.info` dictionary | ||
with the key `blurhash`. It is a BlurHash of the original piece of media. | ||
Clients could then render this using [one of the available BlurHash | ||
implementations](https://github.com/woltapp/blurhash). | ||
|
||
This would be optionally displayed while the thumbnail of the media is loaded | ||
in parallel. | ||
|
||
Example `m.room.message` content: | ||
|
||
```json | ||
{ | ||
"body": "image.png", | ||
"info": { | ||
"size": 149234, | ||
"mimetype": "image/png", | ||
"thumbnail_info": { | ||
"w": 301, | ||
"h": 193, | ||
"mimetype": "image/png", | ||
"size": 72958 | ||
}, | ||
"w": 301, | ||
"h": 193, | ||
"thumbnail_url": "mxc://example.org/abcdefg", | ||
"blurhash": "JadR*.7kCMdnj" | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
"msgtype": "m.image", | ||
"url": "mxc://example.org/abcde" | ||
} | ||
``` | ||
|
||
Note that a BlurHash representation is really only applicable to media, and | ||
as such should only be used in conjunction with the following | ||
`m.room.message` msgtypes: | ||
|
||
* `m.image` | ||
* `m.video` | ||
|
||
### m.sticker | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. random thought: it might be worth defining a "shape" next to the blurhash where a polygon of max 12 points (or whatever) can be defined There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds like you want to maintain cross-platform libraries which extend blurhash with generic path masking :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I now realize this is a no-go. A square sticker isn't that bad: clients might want to put a circle or something around it as a border to match the rough shape of most stickers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One hacky solution is to generate a blurhash on black and a blurhash on white, the client can then pick the once closest to the theme. But that doubles the storage space. If you wanted to get super fancy a client can probably diff the two and tease the transparency info out. But I don't want to mandate that in the spec. (I would rather wait for a blurhashv2 to come out with transparency support). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tbh I disagree, only because stickers look broken with a full-frame blurhash. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current state of blurhash not supporting transparency (and little movement on this front from the upstream library) is a good sign to potentially back away from supporting blurhashes for The path data sounds like a potential solution, and other messages services such as Telegram indeed use that method to great effect. Some thought will need to be given to animated stickers though, and what frame should be used when capturing a silhouette of the media (the first frame would not always be effective). Blurhashes in a sticker picker also seems less useful than silhouettes when searching for a known sticker on a slow network connection. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious whether ThumbHash would address this sufficiently: https://github.com/evanw/thumbhash There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cvwright thanks for bringing that up, not heard of it before and the comparison looks good visually - https://evanw.github.io/thumbhash/ Only has few implementations currently though There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still think the "rough path outline" solution might be more visually appealing for stickers? Observe how Telegram employs it while stickers are loading in the picker. I think this would be much more appealing than blurry thumbnails: We shouldn't discount using ThumbHash elsewhere though (see the other discussion on it #2448 (comment)). |
||
|
||
An optional field is added to `m.sticker`'s `content.info` dictionary with | ||
the key `blurhash`. Its value is a BlurHash of the sticker media. | ||
|
||
Example `m.sticker` content: | ||
|
||
```json | ||
{ | ||
"body": "Landing", | ||
"info": { | ||
"h": 200, | ||
"mimetype": "image/png", | ||
"size": 73602, | ||
"thumbnail_info": { | ||
"h": 200, | ||
"mimetype": "image/png", | ||
"size": 73602, | ||
"w": 140 | ||
}, | ||
"thumbnail_url": "mxc://matrix.org/sHhqkFCvSkFwtmvtETOtKnLP", | ||
"w": 140, | ||
"blurhash": "JadR*.7kCMdnj" | ||
}, | ||
"url": "mxc://matrix.org/sHhqkFCvSkFwtmvtETOtKnLP" | ||
} | ||
``` | ||
|
||
### m.room.avatar | ||
|
||
Room avatars having BlurHashes available will be especially useful when | ||
viewing a server's Public Rooms directory. | ||
|
||
An optional field is added to `m.room.avatar`'s `content.info` dictionary with the | ||
key `blurhash`. Its value is a BlurHash of the media that is pointed to by | ||
`url`. | ||
|
||
Example `m.room.avatar` content: | ||
|
||
```json | ||
{ | ||
"url": "mxc://matrix.example.com/a59ee02f180677d83d1b57d366127f8e1afdd4ed", | ||
"info": { | ||
"blurhash": "JadR*.7kCMdnj" | ||
KitsuneRal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
``` | ||
|
||
### m.room.member | ||
|
||
Much like room avatars, user avatars can have BlurHashes as well. There is a | ||
little more required to implement this, but the outcome of no longer having | ||
missing avatars upon opening a room is worthwhile. | ||
|
||
An optional field is added to `m.room.member`'s `content` dictionary with | ||
the key `blurhash`. Its value is a BlurHash of the media that is pointed | ||
to by `avatar_url`. | ||
|
||
Note that `blurhash` MUST be omitted if `avatar_url` is not present. | ||
|
||
Example `m.room.member` event content: | ||
|
||
```json | ||
{ | ||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF", | ||
"displayname": "Alice Margatroid", | ||
"membership": "join", | ||
"blurhash": "JadR*.7kCMdnj" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm: why is this on the top level but the room avatar isn't? should we just move the room avatar one up a level and call it good? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The justification for it is that The inconsistency is indeed a bit awkward. If we move I'm curious what others think the best way forward is. |
||
} | ||
``` | ||
|
||
### Profile endpoints | ||
|
||
Endpoints that return profile information, and thus MXC URLs to user avatars, are | ||
extended to optionally include BlurHashes as well. | ||
|
||
[`GET /_matrix/client/v3/profile/{userId}`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv3profileuserid) | ||
has an optional field added with | ||
the key `blurhash`. Its value is a BlurHash of the media that is pointed to | ||
by `avatar_url`. `blurhash` MUST be omitted if `avatar_url` is not present. | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
The same applies | ||
to [`GET /_matrix/client/v3/profile/{userId}/avatar_url`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv3profileuseridavatar_url) | ||
, and to the federation | ||
endpoint [`GET /_matrix/federation/v1/query/profile`](https://spec.matrix.org/v1.3/server-server-api/#get_matrixfederationv1queryprofile) | ||
. | ||
|
||
#### Example responses: | ||
|
||
`GET /_matrix/client/v3/profile/{userId}` | ||
|
||
```json5 | ||
{ | ||
"avatar_url": "mxc://matrix.org/SDGdghriugerRg", | ||
"displayname": "Alice Margatroid", | ||
"blurhash": "oyp8ky2BWn7VHEL" | ||
} | ||
``` | ||
|
||
`GET /_matrix/federation/v1/query/profile` | ||
|
||
```json5 | ||
{ | ||
"avatar_url": "mxc://matrix.org/SDGdghriugerRg", | ||
"displayname": "Alice Margatroid", | ||
"blurhash": "oyp8ky2BWn7VHEL" | ||
} | ||
``` | ||
|
||
`GET /_matrix/client/v3/profile/{userId}/avatar_url` | ||
|
||
```json5 | ||
{ | ||
"avatar_url": "mxc://matrix.org/SDGdghriugerRg", | ||
"blurhash": "oyp8ky2BWn7VHEL" | ||
} | ||
``` | ||
|
||
Separately, [`PUT /_matrix/client/v3/profile/{userId}/avatar_url`](https://spec.matrix.org/v1.3/client-server-api/#put_matrixclientv3profileuseridavatar_url) | ||
has an optional field added | ||
to the request body with the key `blurhash`. Its value is a BlurHash of the media that is pointed to by the value of | ||
the `avatar_url` field in the same request. | ||
|
||
#### Example request/response interaction | ||
|
||
Request: | ||
``` | ||
PUT /_matrix/client/v3/profile/{userId}/avatar_url HTTP/1.1 | ||
|
||
{ | ||
"avatar_url": "mxc://matrix.org/SDGdghriugerRg", | ||
"blurhash": "oyp8ky2BWn7VHEL" | ||
} | ||
``` | ||
|
||
Successful response: | ||
|
||
``` | ||
200 OK | ||
|
||
{} | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
### URL previews | ||
|
||
An optional attribute is added to the OpenGraph data returned by a call | ||
to | ||
[`GET /_matrix/media/v3/preview_url`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixmediav3preview_url) | ||
called `matrix:image:blurhash`. The value | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
of this attribute is the blurhash representation of the media specified | ||
by `og:image`. Note that we place this value under the `matrix` namespace as | ||
the [OpenGraph protocol](https://ogp.me/) does not (yet) have a spec'd field | ||
for BlurHashes. | ||
|
||
Note that `matrix:image:blurhash` MUST be omitted if `og:image` is not present | ||
in the response. | ||
|
||
Example response to `GET /_matrix/media/v3/preview_url`: | ||
|
||
```json | ||
{ | ||
"og:title": "Matrix Blog Post", | ||
"og:description": "This is a really cool blog post from matrix.org", | ||
"og:image": "mxc://example.com/ascERGshawAWawugaAcauga", | ||
"og:image:type": "image/png", | ||
"og:image:height": 48, | ||
"og:image:width": 48, | ||
"matrix:image:size": 102400, | ||
"matrix:image:blurhash": "oyp8ky2BWn7VHEL" | ||
} | ||
``` | ||
|
||
### Inline images | ||
|
||
An optional attribute is added to `<img>` tags in messages: | ||
`data-mx-blurhash`, where the value of the attribute is the blurhash | ||
representation of the inline image. | ||
|
||
This would be optionally displayed while the inline image itself is loaded in | ||
parallel. | ||
|
||
Example `m.room.message.formatted_body`: | ||
|
||
``` | ||
"formatted_body": This is awesome <img alt=\"flutterjoy\" title=\"flutterjoy\" height=\"32\" src=\"mxc://matrix.example.org/abc\" data-mx-blurhash=\"LEHV6nWB2yk8pyo\" /> | ||
``` | ||
|
||
## Calculating a blurhash on the server | ||
|
||
BlurHashes are inserted into events by the client, however some clients may not | ||
be able to implement the BlurHash library for whatever reason. In this case, it | ||
would be nice to allow the media repository to calculate the BlurHash of a piece | ||
of media for the client, similar to how thumbnails are calculated by media | ||
repositories today. | ||
Comment on lines
+253
to
+257
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's roughly two years on. Are there any valid use cases that we're aware of for this endpoint today? I don't know of any clients that have needed to rely on it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. Element sometimes relies on the media repo for thumbnails, but that doesn't work in encrypted rooms anyway and I haven't seen any client using that endpoint nor any server supporting it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. I'm going to rip it out of this MSC then. cc @turt2live who originally(?) proposed it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been chasing memory allocation issues related to blurhashes in matrix-media-repo (MMR), and my conclusion is I agree with this conclusion. Element is not using the returned field, and most/all of the bridges I can test quickly aren't using it either. This makes it fairly pointless for servers to support. For added context, the allocation issue is with the input for calculating a blurhash. The blurhash itself is a non-issue. Specifically, jpegs are awful. |
||
|
||
A new boolean query parameter, `generate_blurhash`, is added to | ||
[`POST /_matrix/media/v3/upload`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixmediav3upload) | ||
which allows clients to ask the server to generate a BlurHash for them. This | ||
may be useful for clients that are designed to run on very low-power hardware, | ||
or otherwise cannot generate a BlurHash itself. | ||
If set to `true`, the server SHOULD generate a BlurHash of the uploaded media | ||
and return it as the value of the `blurhash` key in the response. | ||
|
||
If the server cannot generate a BlurHash of the media - perhaps because it is | ||
not a file that a BlurHash can be derived from or it is too expensive to process | ||
a very large piece of media - then the server SHOULD NOT return a `blurhash` key | ||
in the response. Additionally, if `generate_blurhash` is not `true`, then the | ||
server SHOULD NOT return a `blurhash` key in the response. | ||
|
||
Fundamentally, this means that clients SHOULD NOT assume that a server will always | ||
return a BlurHash in the response to `/_matrix/media/v3/upload`, even if they have | ||
set the `generate_blurhash` query parameter to `true` in the request. | ||
|
||
An example request from a client that would like the server to generate a | ||
blurhash would look like: | ||
|
||
``` | ||
POST /_matrix/media/v3/upload?generate_blurhash=true&filename=My+Family+Photo.jpeg HTTP/1.1 | ||
Content-Type: image/jpeg | ||
|
||
<bytes> | ||
``` | ||
|
||
Example response: | ||
|
||
``` | ||
{ | ||
"content_uri": "mxc://example.com/abcde123", | ||
"blurhash": "LKO2?U%2Tw=w]~RB" | ||
} | ||
``` | ||
|
||
We explicitly make this behaviour opt-in as it is assumed that the majority of | ||
clients that end up supporting BlurHashes will be capable of generating them | ||
locally. Thus, the less load we can put on the homeserver (by not making | ||
blurhash generation the default) the better. | ||
|
||
Note that media servers will not be able to return a BlurHash string for | ||
encrypted media; that must be left to the client. | ||
|
||
The server could additionally return the BlurHash string for an image when | ||
given an MXC URL. This would be through something like the Media Information | ||
API (specified in | ||
[MSC2380](https://github.com/matrix-org/matrix-doc/pull/2380)), or similar. | ||
|
||
## Visualisation | ||
|
||
Viewing an image message that is loading: | ||
|
||
 | ||
|
||
Once the image loads: | ||
|
||
 | ||
|
||
As a sample, this is Element's behaviour prior to this MSC's introduction: | ||
|
||
 | ||
|
||
## Alternatives | ||
|
||
We could include a base64 thumbnail of the image in the event, but blurhash | ||
produces much more efficient textual representations. | ||
Comment on lines
+323
to
+326
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discuss the alternative algorithm (and self-proclaimed improvement over BlurHash) ThumbHash. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The alpha support is nice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A comparison of ThumbHash vs. BlurHash. ProsAlpha supportThumbHash handles images with transparent backgrounds in a much nicer fashion than BlurHash. While the obvious use case for this is stickers, as mentioned elsewhere, I think that vector outlines would be the best way to represent stickers before they are downloaded in full resolution. Still, being able to somewhat make out what an image with a transparent background is before it has loaded is valuable. Better qualityThumbHash appears to generally create a better representation of the image than BlurHash (examples taken from https://evanw.github.io/thumbhash/): ConsLimited Library SupportBlurHash was one of the first to widely publicise this use case, and thus it is a lot more popular than ThumbHash. Compare the number of implementations for ThumbHash versus BlurHash. Still, the algorithm is so simple that you could presumably translate it into your chosen language in about 30m. BlurHash is already widely used in MatrixAgain, due to BlurHash coming out much earlier than ThumbHash, Matrix clients have already implemented BlurHash (through this MSC) widely. If we switch, clients with concern for backwards-compatibility will likely need to implement both BlurHash and ThumbHash. However, currently BlurHash mostly applies to media sent in the timeline, which quickly becomes stale. Element Web only supports The more pressing concern would be interacting with older clients that still only send BlurHashes instead of ThumbHashes. However the failure mode here during the transition period wouldn't be too bad - you just won't see blurred thumbnails. BandwidthTODO: I'd like to conduct a test of both algorithms over a range of, say, 100 images. Using base83 encoding for both. Currently I'm not sure whether BlurHash or ThumbHash generally produces smaller encoding sizes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ThumbHash is also around 10x faster to generate, at least on iOS. I can run a little experiment and report the results if there's interest. The Circles client is no longer generating BlurHashes. We will continue to display them but we are moving entirely to ThumbHash for the future. The slow performance was a big part of this, but also ThumbHash just seems to work better all around. For example, we were having issues on Android where the BlurHash code crashed the app on an invalid input. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As the person who implemented Blurhash based on this MSC in Element Web I'm all for switching to something which supports alpha and has better performance, maintaining blurhash rendering similar to how @cvwright described another client handling it for some time is acceptable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I downsample the source image once to 100x100. Then from that 100x100 I create the ThumbHash and the BlurHash. Maybe the Swift ThumbHash implementation is just more optimized than the BlurHash version? The author went to some pretty great lengths to make it fast. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't look particularly optimized, but neither was the blurhash implementation, I guess. But feel free to bench it. Seems like I was also wrong, the hashing doesn't downscale first, but rendering the blurhash does create a 32x32 pixels image at best, which would be 10x faster than creating a 100x100 pixels image. So would be interesting to see comparisons, especially if you include my lib: https://github.com/Nheko-Reborn/blurhash :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cvwright If you are doing a benchmark, reporting on the resulting filesizes of the hashes would be appreciated! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @anoadragon453 if this is to progress we probably need to update the MSC to define the field for the thumbhash to live. The lack of alpha channel in blurhash makes it insufficient in my opinion. I have a PoC impl for EW which sends & renders both blurhash & thumbhash, preferring the latter for rendering when available. PoC: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ruma has implemented support for ThumbHash in ruma/ruma#2059. |
||
|
||
## Backwards compatibility | ||
|
||
Older clients would ignore the new `blurhash` parameter. | ||
|
||
Newer clients would only show it if it exists. | ||
|
||
Users who have not specified `blurhash` in their `m.room.member` event yet may | ||
stand out from users who have while both are loading. This is entirely up to | ||
clients to handle, though a suggestion may be to "fake" a blurhash by | ||
blurring some placeholder image (perhaps something with variation between | ||
users like Element's coloured backgrounds with letters in them, or [an | ||
identicon](https://en.wikipedia.org/wiki/Identicon) derived from the user's | ||
ID) until the user's actual avatar loads. | ||
|
||
## Unstable prefixes | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Implementations wishing to add this before this MSC is merged can do so with | ||
the following: | ||
|
||
* The `blurhash` key in any events, request or response bodies should be | ||
replaced with `xyz.amorgan.blurhash`. | ||
|
||
* `/_matrix/media/v3/upload`'s new `generate_blurhash` query parameter | ||
should instead be `xyz.amorgan.generate_blurhash`. And instead of the | ||
key `blurhash`, the endpoint should return `xyz.amorgan.blurhash`. | ||
|
||
* The `data-mx-blurhash` attribute in `<img>` tags should be replaced with | ||
`data-xyz-amorgan-blurhash`. | ||
|
||
## Security considerations | ||
|
||
BlurHash entries in encrypted events, be it as part of the `info` property, | ||
or `<img>` tags, should be encrypted along with the rest of the event | ||
content. | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
A [discussion in | ||
#matrix-spec](https://matrix.to/#/!NasysSDfxKxZBzJJoE:matrix.org/$Cfa0dtF3DenIUAbC5aeg3Xo10gAF54mAJLZ6VzvYNfo?via=matrix.org&via=amorgan.xyz&via=pixie.town) | ||
questioned whether massive BlurHashes may be a potential DoS vector for | ||
clients. The discussion found that only a maximum of 100 x 100 components can | ||
be defined by a BlurHash. This may be in the higher range for low-resource | ||
(or unoptimised) clients, and clients are free to refuse to render a BlurHash | ||
with a large component count, but it shouldn't be a cause for concern. | ||
|
||
Invalid BlurHashes should not be rendered. | ||
|
||
## Links | ||
|
||
BlurHash's algorithm description can be found | ||
[here](https://github.com/woltapp/blurhash/blob/master/Algorithm.md), which | ||
also includes the full output character set. |
Uh oh!
There was an error while loading. Please reload this page.