-
Notifications
You must be signed in to change notification settings - Fork 2
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
Make it easy to crop image pixels or update images by character cells. #28
Comments
i'd disagree with this. Notcurses is, as far as i'm aware, the only terminal ui library with reasonable bitmap support. it absolutely does not want to restrict itself to character cells at a time, and does not require this from users, who can feed it an arbitrary bitmap and arbitrary pixel coordinates, and have this interact sanely with text. it goes to fairly extreme lengths to make this work, but it works well (see https://www.youtube.com/watch?v=dcjkezf1ARY) https://github.com/dankamongmen/notcurses/blob/8f972a3e0e638191e143845c5b980bb17c6936c6/src/lib/termdesc.h#L112 <-------------- some of the pixel information notcurses derives regarding the terminal |
@amano-kenji I'm in support of and can testify to your first statement:
but not the rest. Drawing graphics cell-by-cell might seem very attractive and useful to TUI developers but will be tedious for terminal emulator developers. This will require encoding/compressing (on the application's end) and decoding/decompressing (on the terminal emulator's end) pixel data cell-by-cell, which is a really bad idea considering the encoding/compression time on the application's end, amount of memory used on the application's end (if storing the escape sequences), transmission time and decompression/decoding time on the terminal emulator's end. At least, from my little experience, I've encoded images line-by-line and I can say that the difference between that and encoding images as a whole is quite clear. Some terminal emulators barely cope with the "line-by-line" images (though IMO that is mostly due to their bad design) e.g iTerm2. |
Okay. But, it's good to be able to fill character cells fully by knowing how many image pixels fit in a charater cell vertically and horizontally. |
For TUI libraries, cropping images by character cells is going to be important. To do that, they need to know how many image pixels fit in a character cell. |
It may actually be the place of a graphics protocol to specify a means for this but there are already a couple known methods:
It's possible for a graphics protocol to define an APC for this purpose but I'm not sure it's necessary. EDIT: Added some points for completeness. |
Then, a graphics protocol may define |
There is a possibility that physical pixels of a terminal emulator may not be of the same size as image pixels. |
No, it can't because:
The best that can be done IMO is to define an APC (Application Program Command; See ECMA-48 Section 8.3.2 Pg 33) or some other non-conflicting control sequence.
I don't understand 🤔. Care to explain? |
https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/26#note_1770479 |
Oh, I see. You're talking about retina/HiDPI displays. IMO, that's really for the terminal emulator to handle. As long as the terminal emulator uses the same dimensions (physical or logical) it reports to an application to process and render the pixel data sent by that application, it won't matter to the application which kind of dimensions the terminal emulator reports. By the way, I had no idea that |
Maybe, we should do this? |
Why would you want to though? Can you site one case where the existing methods do not suffice on a terminal emulator that actually implements a graphics protocol? |
You are the one who said
I want the best |
I meant the best, if it had to be done. Remember what I also said before that:
|
haskell vty library records what each character cell contains in order to know which character cells to update. For images, each rendered character cell would have to contain the hash of image pixels in the character cell or the entire image. Should it be the hash for image pixels in a character cell or an entire image? |
This depends. My approach from the start has been to keep the hash (of the image string, not of the pixels) of the complete image in the cell, along with the position (row/col info to map the image) info. It works well and is battle-tested. But of course, my approach assumes that there is -still- no new/modern image protocol. |
What is image string? |
the image is usually a sixel stirng or a base64 encoded (passed as string via sequences, I mean). Hashing the decompressed and drawn image is expensive than hashing a |
You mean compressed terminal image encoding of an image. |
I think the hash for terminal encoding of the entire image and the position info should be enough. |
Yes, that's what I mean. |
So, terminal emulator developers want an entire image to be drawn at once? |
By the way,
|
That info can be supplied to vte via the "new" protocol, or the host app can send partial images (some TUIs do just that.) |
Do you calculate character cells of an image that should be updated? Or, do you just draw an entire image every time? |
No, I calculate and draw only the updated portions. |
What's your algorithm for calculating updated portions of an image? My algorithm would be to calculate multiple contiguous portions of an image and draw one contiguous portion at a time. |
Exactly :) |
That's the optimal way -IME. |
If I draw an entire image and then draw another layer on top, then people will see flickers before the above layer is drawn? |
I wish it was efficient to draw an image cell by cell so that I don't have to calculate contiguous character cell portions of an image... |
Well, that depends on the drawing methods your vte uses. It can be designed to refresh down to a singe cell-level, but I have restrictions stemming from the toolkit I use, so I never tried that. But it can be done. In my case it would be suboptimal... |
If a terminal emulator uses double buffering, then drawing an entire image and drawing another layer on top can be done without flickering. The most painless way for TUI developers would be to just draw an image cell by cell. |
What's the toolkit you use? |
You can take a look at here, for what can be done, and get some visual ideas (follow the links) |
U++ , A C++ RAD toolkit. |
What approach? Cell-by-cell drawing? Or, double buffering? Or, contiguous character cell portions of image? |
Many terminal UI libraries would prefer to just display images in given character cells(for example, 30 columns 20 rows) and update images cell by cell.
Is it going to be inefficient to draw an image for the first time cell by cell? Updating an image cell by cell could be efficient.
To manipulate images cell by cell, programmers would need to know how many image pixels fit in a character cell horizontally and vertically. Physical pixels of a terminal emulator may not have the same size as image pixels.
Haskell's vty library only knows character cells. It doesn't know image pixels. If vty was able to draw an image cell by cell efficiently, it could support images easily. Because vty has to know what each character cell contains in order to know which character cells to actually update, it wouldn't use alpha channel in image pixels. For example, drawing a partially transparent image character cell over a text character cell would complicate the computation of whether a character cell needs to be updated.
The text was updated successfully, but these errors were encountered: