-
-
Notifications
You must be signed in to change notification settings - Fork 284
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
"sub-pixel" glyphs? #28
Comments
Do you mean derasterize? |
Yes! Sort of :-P Probably that can be used, yes :-) The proposed option of using sixels at #11 could be another alternative too :-) |
Definitely a good idea! Someone shared https://github.com/matrach/img2unicode which also produces pretty good results. |
This is more alike I was asking about, but also taking in consideration triangular shape glyhps and diagonals and so, so they can provide a better adjustment. I think there was a project that was using Machine Learning to get the Unicode character that better fits the actual image... |
Hi all. My proof of concept tool (https://github.com/matrach/img2unicode) uses some ML -- optimization with (Approximate) Nearest Neighbors to be exact. For each chunk of an image (i.e. 16x32 px), the tool basically selects a glyph (from a prerendered dataset) that optimizes both:
The need to use ML arose from the need to support arbitrary Unicode glyphs. This is not easily portable while maintaining the rendering quality, because there is a lot of variability between rendering by different terminal backends (e.g., libvte, kitty, etc.) and fonts. The triangular shapes were added to Unicode 13 (Legacy Computing Symbols) in 2020, and at the time of writing of the tool, they were rarely supported by terminal rendering backends. (And probably are still not supported on Ubuntu 20.04 LTS' default terminal.) If you haven't already, I'd suggest looking at tools like https://github.com/dankamongmen/notcurses that can transparently select image rendering with sixels, Kitty's Terminal graphics protocol, or fallback to standard blocks. |
Thank you for the detailed explain :-D |
I considered notcurses, but it does not seem optimized for real-time rendering at 60fps unfortunately. For example, a good SIXEL implementation for us would need adaptative quantization (only run it on a few frames and re-use the palette on others) as it's the most expensive step. I've been experimenting with this sub-pixel idea, and ended up with this pretty fast algorithm using a mask and a table lookup (<1ms per frame, seems to be auto-vectorize well on arm64): Lines 3 to 41 in 50c2547
Results are interesting, note the building edges (just doing images for now):
|
Quadrant binarization looks pretty good! :-) I was personally thinking about the triangular glyphs, but your algorythm using quadrants works pretty well, and doubt we can get something better without seeing some artifacts due to not having homogeneous "pixels", good work :-) |
Not sure if it's useful, but I have made an image viewer in the awk scripting language which uses the unicode quadrant blocks, making use of some self made up color mixer. If it's useful then feel free to use it. if it's not, then that's fine. |
@patsie75 Your code is licensed under GPL-3.0 and Carbonyl is Modified BSD. I'm not sure they are 100% compatible: "The GPL would allow you distribute the interface within another work only if that whole larger work were licensed under the GPL." |
No, they are not compatible, but since they are in different languages (awk vs rust), I'm not sure if the translation would be covered by the GPL license... |
Note that thresholding by luma is probably suboptimal, since if you have a block such that a top half is red and a bottom half is green (with matching luminescence), then this algorithm would use a full block instead of The img2unicode algorithm for block glyphs (glyphs rendered with consistent brightness without grayscale) is easily vectorized since it is just a matrix (tensor, really) multiplication. Thanks to this topic, I've finally described how the optimization for block-shapes works 😄 : https://github.com/matrach/img2unicode/blob/master/README.md#details-of-fastgenericdualoptimizer By the way, a while ago I also had prepared a selection of images for the evaluation of such methods. You can find them here: https://github.com/matrach/img2unicode-demos/tree/master/images |
I just merged this feature to master, I also added a $ docker run -ti -e COLORTERM=24bit fathyb/carbonyl:next https://youtube.fr --zoom=300 --bitmap CleanShot.2023-02-14.at.05.44.26.mp4
I did notice that and fixed it by always using two blocks: Lines 21 to 39 in 6747498
Agreed on luma being suboptimal, but it's pretty fast to compute. I'm going to take a deeper look at your description, not very well versed in math 😅 But feel free to open a PR, that's definitely something I want. |
Instead of just only use lower block glyph, try to detect actual image shape and use glyphs that better adapt to it, like diagonals and so.
The text was updated successfully, but these errors were encountered: