Menu

#126 [DRAFT] [feature] [ts] add image component

closed
nobody
None
2025-08-25
2025-08-25
Anonymous
No

Originally created by: endernoke

Related to [#104]
This PR introduces a new modular and extensible image rendering system for terminal UIs, supporting multiple protocols for displaying images using different techniques.

Changes (high level:

  • Added a unified Image component interface
  • implemented two new image rendering protocols (HalfBlock and Braille)
  • Introduced a protocol factory for easy extensibility,

Image component

<Image> handles image fetching, resizing, and conversion to terminal-friendly output.
Props:

  • src: file path or URL to image
  • Accepts png/jpg, webp, possibly svg and tif but haven't tested
  • width, height (optional): display width and height of the image (in terminal cells).
  • If not set, width and height will be inferred from available space in parent component and the aspect ratio of the original image.
  • Note that on most terminals the cell height is roughly twice the cell width, so for example a square image should have its height set to half its width to maintain aspect ratio
  • protocol (optional): the rendering backend to use, currently either halfBlock or braille.

New image rendering protocols

halfBlock:

  • Uses the unicode lower half block character ("▄",, U+2584) with ANSI escape sequences for text color and background color
  • Resolution: 1x2 pixels per terminal cell

Braille:

  • Uses eight dot braille characters (U+2800 to U+2899) to render a monochrome image
  • Resolution: 2x4 pixels per terminal cell

To-do / technical debt

  • Convert image protocol factory from class-based to functional for better compatibility with React
  • Implement ASCII rendering based on original feed display
  • Keep experimenting with iterm2, kitty, sixel, and other native terminal image protocols which allows full resolution.
    Since Ink doesn't support custom terminal rendering natively we need to manually figure out the correct coordinates in the terminal where the image should be rendered, then render the image via a side-effect, then clean up / redraw the image when component moves or unmounts (At this point I'm not very optimistic about this 💀 The code for rendering sixel is in ts-migration/image-sixel)

Related

Tickets: #104
Tickets: #127

Discussion

  • Anonymous

    Anonymous - 2025-08-25

    Originally posted by: endernoke

    Confirmed to work on iterm2 😄, agrees with the structure and would be great to add docstring before this is merged since it's a important shared util

    Should we convert this into a npm library and install back to this project, thinking this would give it more robust community support and our repo won't be cluttered with terminal compatibility issues lmao

     
  • Anonymous

    Anonymous - 2025-08-25

    Ticket changed by: endernoke

    • status: open --> closed
     
  • Anonymous

    Anonymous - 2025-08-25

    Originally posted by: endernoke

    Sorry pushed to the wrong branch 😅 , reverted

     

Log in to post a comment.

Auth0 Logo