Open quincynyan opened 10 months ago
Hi, thanks for bringing it up. I need a little more information, so I can figure out if/how this idea could apply more generally.
It would be great to have a screenshot of how it looks in Neofetch. Is the problem actually that it's misaligned there, or is it important to have the spacing when you run chafa
standalone from the command-line too?
Thanks, that explains the request perfectly.
The good news is that chafa
will get more ways to position the image in the next release. See #140 and #146. It should be able to do what you want.
The bad news is that --yoffset
is actually an argument to neofetch
, which calls chafa
like this:
chafa --stretch --size="$((width / font_width))x$((height / font_height))" "$image"
There's no positioning information there, so it would be necessary to patch Neofetch to pass it on to Chafa. And unfortunately, its developer seems to be on hiatus still. Might be possible to get traction for it in one of the forks, though.
I just released version 1.14.0. It has the new options --view-size
and --align
, which can be used to produce vertical spacing. I chose to use relative positioning instead of absolute, since it simultaneously addresses other use cases.
You can add a one-line vertical offset like this:
chafa image.jpg --view-size 20x10 --size 20x9 --align bottom
Unfortunately there's nothing I can do about Neofetch directly. Hope it's useful anyway!
Those are nice new features! I'm writing my own version of neofetch and want to replicate this behavior:
Without any offset:
With 32px offset from top and 20px offset from left (offset_y variable is 32, offset_x variable is 20)
printf '%b\n%s;\n%s\n' "0;1;$xoffset;$yoffset;$width;$width;;;;;$tmpfile.$format" 3 4 | /usr/lib/w3m/w3mimgdisplay &>/dev/null
. I don't know how w3m does it but in chafa, I can only move the image down or right by specific amount of row or columns, i.e. by changing where the cursor is. This limits me to the grid of the terminal. The only thing i can think of is printing empty lines and then drawing the image, but these dont work for exact numbers of pixels. The image shows up under exact numbers of lines, like for e.g. 1 line below the initial line, or 2 lines below, or exactly 3 lines below. Not 1 pixel, 20 pixels, 15 pixels, 1.5 lines, etc. But w3m seems to be able to do it.
chafa image.jpb --yoffset 32 --xoffset 20
?
Pixel adjustments are possible with the new smolscale - we could even support cropping if the image is partially outside the viewport, or adjustments in 1/256 fractional pixel increments (but then it'd get blurrier). I'll have a think about how this could fit with the existing options.
We're actually already doing pixel offsets when the image is slightly smaller than the view -- but you can't control the offsets precisely. I.e. --align center
will position it at sub-cell offsets.
I'm adding some text beside and below the image, something like the text wrapping around the image. So pixel offsets would be more useful than the align option in such cases.
If I may chime in...
@quincynyan I'm curious, why would column/row offsets not be okay (or even better)?
@AnonymouX47 I can already kinda implement that behavior bu moving the cursor to wherever I want on the terminal scree and the running chafa. For example, printf '\e[2J\e[H'
to clear the screen and move the cursor to the top left. I can then manually print \n
or spaces to move the displayed image left or down from the top left, then finally call chafa when the cursor is in the position I want. It's basically the same as column/line offset.
The feature I want is something similar to w3mimgdisplay or kitty where you can run kitty +kitten icat --align left --place "$((width/font_width))x$((height/font_height))@${xoffset}x${yoffset}" "$image"
This moves the image by specific pixels from the current cursor position.
I guess I should rephrase my question... Why aren't row and column offsets sufficient? Or Why do you need exact pixel offsets?
Side note: Using CUP (CSI row ; col H
) or CUD (CSI Ps B
) and CUF (CSI Ps F
) sequences would probably be better if you later choose to go the row/column route, since you already clear the screen.
@quincynyan Does it have to be absolute offsets? Would it be enough if the current --align center,center
centered using pixel offsets, for instance?
@AnonymouX47 Sorry I'm late, I've been busy with something for the past couple of days.
I'm making a bash script CLI app which allows the user to position where their image will be displayed (and also choose which display backend they want to use). This is through the --xoffset
and --yoffset
options. Of course, I could make the options only take in the number of columns/rows, but I've already made it say they take in pixel values, and have implemented w3m and kitty image backends to use pixel offsets. I could change them so that they are number rows/columns, and multiply by the resolution/number of pixels in height/width then pass it to w3m or kitty, but something like a 4px offset from the top of the terminal looks way better than an entire row offset from the top when display an image. 0px is too little and 1 row looks like a too empty gap above the image.
@hpjansson I already know the widths and heights of the image, and so maybe what I can do is create an empty space/canvas of (width+xoffset) x (height+yoffset), then --align
the image to be printed in bottom right of the given space/canvas. Is that possible? Again, I'm also going to be printing around (right and bottom) the image, but using space padding that's calculated using the (width+xoffset) x (height+yoffset)
and the image stays on "top" of that strings of spaces.
@AnonymouX47 Sorry I'm late, I've been busy with something for the past couple of days.
I'm making a bash script CLI app which allows the user to position where their image will be displayed (and also choose which display backend they want to use). This is through the
--xoffset
and--yoffset
options. Of course, I could make the options only take in the number of columns/rows, but I've already made it say they take in pixel values, and have implemented w3m and kitty image backends to use pixel offsets. I could change them so that they are number rows/columns, and multiply by the resolution/number of pixels in height/width then pass it to w3m or kitty, but something like a 4px offset from the top of the terminal looks way better than an entire row offset from the top when display an image. 0px is too little and 1 row looks like a too empty gap above the image.
Hmm... I see.
Again, it's not a requirement, it's just a feature request. If not possible, I'll try to reverse engineer how w3m does it and maybe port it to my app. The problem is I don't really know C language so it's hard reading the source code lmao
One important thing to note is, only the Kitty graphics protocol supports pixel offsets for image placements. For the record, w3mimgdisplay
doesn't actually display images within the TE, it uses overlay/floating windows that have no chrome/decoration.
Anyways, like @hpjansson mentioned, it's possible to mimick the behaviour... I would imagine by compositing the original image (after being appropriately scaled; not source image) onto the lower-right region of a transparent canvas of size image_width + x_offset
by image_height + y_offset
.
The only issues I can think of at the moment are:
The reason I created this issue was to resolve this issue:
https://cdn.nekonyan.fun/Peek_2023-09-09_10-22.gif
I know the author is on hiatus and isn't currently accepting any pull requests, but I can fork my own version of it and fix it.
Here is the code for w3m
:
printf '%b\n%s;\n%s\n' "0;1;$xoffset;$yoffset;$width;$width;;;;;$tmpfile.$format" 3 4 | /usr/lib/w3m/w3mimgdisplay &>/dev/null
Here is the code for kitty
:
kitty +kitten icat --align left --place "$((width/font_width))x$((height/font_height))@${xoffset}x${yoffset}" "$image"
Here is the code for chafa
:
chafa --stretch --size="$((width / font_width))x$((height / font_height))" "$image"
As hp mentioned, there is no information passed about offsets there. So how would the offsets information be passed on to chafa so that it renders the image correctly just like it does in w3m and kitty? I've implemented both w3m and kitty in my fork, but don't know how to implement chafa. Again, I'm measuring the offsets starting from the current position of the cursor after clearing the screen and moving the cursor to the top left.
I am using chafa together with neofetch, but the image outputted is printed at the top of the terminal, i want it around 50 pixels moved down. This can be done with the
--yoffset 50
in w3m, but can't find something similar in chafa. Maybe like some sort of padding above the image? When I just runchafa image.png
, I want some space between the current line of the command (where i typed and entered the command) and the top of the image by some amount of pixels specified by me.