-
Notifications
You must be signed in to change notification settings - Fork 242
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
Embedded raster graphics images #132
Comments
Not enough standard support across terminals yet... Deferring for some time. |
Looks like that w3m library is drawing directly to the screen in some cases, which will never work on a true terminal, so I'm not sure I'd want it in by default. Possibly an optional extra? |
Here is my semi-working version of sixel support. It only seems to work correctly when the terminal is full screen. I believe it may have something to do with using _width and _height, but it may also be the use of TextBox for it. Any pointers would be appreciated. `def sixel(image, x, y, max_w, max_h):
Example function call.
|
That's a good start! The worry I have is how to decide whether to allow an application to use something like that API or not. How do you detect the safety of that feature on Linux (all terminal types), MacOS and Windows (native, CygWin, or even cases like PuTTY connecting to a Linux server)? |
As far as I know, it would have to be on a case by case basis. if "mlterm" in os.environ['TERM'] or "xterm" in os.environ['TERM']: I would have it fallback to a text image using libcaca or something similar. |
Asciimatics already supports image display using text images (without falling back to libcaca). Check out the renderer docs, or images.py sample. My big worry with this feature is that until it is easy for an average user to set up and use on all basic systems, it is going to cause more problems than it solves. We can't insist on an average user doing a custom build of terminals or install non-standard terminals for their OS. And if most users just see the existing feature, is that worth the time and effort? There will also need to be some extra logic added to the Screen objects to recognise when sixel is in use, so that it properly integrates the image with the terminal double-buffering. |
Nice, I hadn't seen the ImageFile function. A universal Image function would make it easy for the user. I did try to use Screen to draw the sixel, but for some reason it strips the escape codes so it just shoots out text to the screen. |
Yeah - you can't print escape codes in the Screen as it is already handling that for you in a cross-platform manner. I need to think about this some more, but I suspect there would need to be some logic for the Screen to be aware which parts are reserved for sixel (and a way to link to the data stream for the image while it should be drawn). There also needs to be some way to spot when the sixel image needs removing (as it gets overwritten) or moving (as the screen scrolls). |
I used textbox for the reserved space, but a dedicated widget for images would be preferable. |
I don't quite understand how you got your custom widget to draw the image at the right time. Could you explain, or share the code? |
It actually tries to draw it before it starts, but that is most likely a simple fix as it didn't do it before I started adjusting some things. Attached is my code. |
Yeah - I get it now. You're bypassing the refresh logic entirely and relying on the fact that asciimatics isn't redrawing in that box because the contents in the double-buffer haven't changed. While it works for this specific case, there are several ways to break that assumption and so this isn't ready for general consumption yet. The Screen object needs to be aware of all the sixel content in the affected text characters and be able to redraw and crop them as needed. Given that this is the most performance critical part of the code, it also needs to be done in such a way that the double-buffering doesn't grind to a halt for large images. |
Here is an updated version that is more integrated (based off TextBox). I made more use of external libraries to shorten the code, but I removed the wand dependency. New dependencies are libsixel-python and python-resize-image. `class ImageBox(Widget):
|
We're getting there... This will work on a single Frame UI, but will not work for one with multiple Frames (or Canvases) as it is drawing over the top of whatever is there without looking at what else is on the Screen. I'm not sure what the best way forwards from here is. Options that spring to mind are:
None of these sound easy and/or make a poor API for the user. |
Looks great, but try putting a second Frame in the Scene that overlaps your image. |
Got it, it eats up part of the image. The sixel would need to be refreshed after the obstructing object that is covering it closes. I assume this is normally handled in the canvas drawing, which can't be used because it strips out escape codes (and maybe other reasons). |
Yep - asciimatics maintains a double buffer for the Screen and any Canvas. It uses this to update any area it thinks has changed when refresh is called. This mechanism needs extending for sixels in some way. You can probably solve the artifact problem by setting the Screen internal cursor state to invalid values. That would result in it just moving the cursor next time it needs to print something. |
I'll have to give some thought on the first part. It would be preferable to keep the widget self-reliant. I tried setting it to invalid values, but it had no effect. I am thinking that the selected item on the ListBox is color-bleeding. If I scroll too fast on the ListBox, I get artifacts in it's scrollbar. When I added a popup box for testing, the artifacts became red which seems to verify this. |
Asciimatics keeps track of the current colour and only changes it when needed. If sixels mess around with the text colour, you'll need to set the current fg, bg and attribute to invalid values to force the next character to be drawn in the right colour. |
I could be wrong, but I suspect that kitty solves the remaining issues with unicode placeholders - see https://sw.kovidgoyal.net/kitty/graphics-protocol/ |
Some terminals support embedding graphical images in the terminal. For example:
It would be nice to be able to make use of this in a cross platform manner.
The text was updated successfully, but these errors were encountered: