Skip to content

Conversation

@alltheseas
Copy link
Collaborator

Summary

Add ThumbHash support for compact image placeholders. ThumbHash offers advantages over BlurHash:

  • Better detail preservation
  • Embedded aspect ratio information
  • Alpha channel (transparency) support
  • More accurate color representation

Implementation:

  • Decode both ThumbHash and BlurHash from imeta tags (prefer ThumbHash)
  • Encode both hashes when uploading images for maximum client compatibility
  • ~25 bytes per hash, minimal overhead

Checklist

Standard PR Checklist

  • I have read (or I am familiar with) the Contribution Guidelines
  • I have tested the changes in this PR
  • I have profiled the changes to ensure there are no performance regressions, or I do not need to profile the changes.
    • Both hashes are calculated concurrently with upload, minimal latency impact
  • I have opened or referred to an existing github issue related to this change.
  • My PR is either small, or I have split it into smaller logical commits that are easier to review
  • I have added the signoff line to all my commits. See Signing off your work
  • I have added appropriate changelog entries for the changes in this PR. See Adding changelog entries
    • I do not need to add a changelog entry. Reason: Will add in follow-up if requested
  • I have added appropriate Closes: or Fixes: tags in the commit messages wherever applicable, or made sure those are not needed. See Submitting patches

Test report

Device: iPhone 15 Pro Simulator

iOS: 17.5

Damus: master + this PR

Setup: Unit tests for encode/decode roundtrip

Steps:

  1. Run xcodebuild test -only-testing:damusTests/ImageMetadataTest
  2. Verify all 7 tests pass

Results:

  • PASS
    • testThumbHashEncodeDecodeRoundtrip
    • testThumbHashBase64Roundtrip
    • testImageMetadataWithThumbHash
    • testImageMetadataWithBothHashes
    • testImageMetadataToTagWithThumbHash
    • testImageMetadataToTagWithBothHashes
    • testRemoveGPSData

Other notes

Commits:

  1. thumbhash: add ThumbHash implementation - MIT-licensed implementation from evanw/thumbhash
  2. thumbhash: add decoding support to ImageMetadata - Parse and decode thumbhash from imeta tags
  3. thumbhash: use ThumbHash for encoding uploaded images - Encode with thumbhash on upload
  4. thumbhash: add ThumbHash.swift to Xcode project - Add to damus, HighlighterActionExtension, ShareExtension targets
  5. thumbhash: add unit tests and fix type name - 7 unit tests
  6. thumbhash: encode both thumbhash AND blurhash for compatibility - Backwards compat with existing clients

References:

alltheseas and others added 6 commits December 14, 2025 22:51
Add ThumbHash library for compact image placeholders. ThumbHash offers
advantages over BlurHash:
- Better detail preservation
- Embedded aspect ratio information
- Alpha channel (transparency) support
- More accurate color representation

Source: https://github.com/evanw/thumbhash (MIT License)

Closes damus-io#3427
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add thumbhash field to ImageMetadata struct
- Update decode_image_metadata() to parse thumbhash from imeta tags
- Update image_metadata_to_tag() to include thumbhash in output
- Add process_thumbhash() to decode base64 thumbhash to UIImage
- Add process_placeholder() helper that prefers thumbhash over blurhash
- Update process_image_metadatas() to use process_placeholder()

This enables displaying ThumbHash placeholders from other clients while
maintaining backwards compatibility with BlurHash.

Closes damus-io#3427
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add calculate_thumbhash() function for encoding UIImage to base64 hash
- Update calculate_image_metadata() to use thumbhash parameter
- Update PostView.handle_upload() to use calculate_thumbhash()

Uploaded images now include thumbhash in their imeta tags, providing
better quality placeholders for other clients.

Closes damus-io#3427
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add ThumbHash.swift to the following targets:
- damus
- HighlighterActionExtension
- ShareExtension

Closes damus-io#3427
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add 5 unit tests for ThumbHash functionality:
  - testThumbHashEncodeDecodeRoundtrip
  - testThumbHashBase64Roundtrip
  - testImageMetadataWithThumbHash
  - testImageMetadataWithBothHashes
  - testImageMetadataToTagWithThumbHash
- Fix ImageMetaProcessState type name (was ImageMetadataProcessState)

Closes damus-io#3427
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Calculate both placeholder hashes concurrently during image upload:
- thumbhash: better quality, aspect ratio, alpha (newer clients)
- blurhash: backwards compatibility with existing Nostr clients

Both hashes are computed in parallel with the upload, so there's
minimal additional latency. The imeta tag now includes both:
  thumbhash <base64> blurhash <string>

Closes damus-io#3427
Signed-off-by: alltheseas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@danieldaquino danieldaquino added the pr-in-queue This PR is waiting in a queue behind their other PRs marked with the label `pr-active-review`. label Dec 15, 2025
@danieldaquino
Copy link
Collaborator

Even if thumbhash might be better in some ways, blurhash is more widely supported around Nostr protocols (https://github.com/search?q=repo%3Anostr-protocol%2Fnips+blurhash&type=code). I have not seen references to thumbhash in the Nostr protocol specs (https://github.com/search?q=repo%3Anostr-protocol%2Fnips+thumbhash&type=code).

@alltheseas, do other Nostr clients support thumbhash?

@alltheseas
Copy link
Collaborator Author

Fevela, and nostria

nostr-protocol/nips#2157

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

media pr-in-queue This PR is waiting in a queue behind their other PRs marked with the label `pr-active-review`.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add thumbhash decoding & encoding

2 participants