Skip to content
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

yoffset option for images like w3m? #164

Open
quincynyan opened this issue Sep 8, 2023 · 17 comments
Open

yoffset option for images like w3m? #164

quincynyan opened this issue Sep 8, 2023 · 17 comments
Labels
feature New feature or request

Comments

@quincynyan
Copy link

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 run chafa 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.

@hpjansson
Copy link
Owner

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.

  • Does "at the top of the terminal" mean that the cursor moves to the very top, overwriting what was already there?
  • Is it using symbol mosaics, sixels, kitty or iterm protocol?

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?

@quincynyan
Copy link
Author

@hpjansson
Copy link
Owner

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.

@hpjansson hpjansson added the feature New feature or request label Sep 10, 2023
@hpjansson
Copy link
Owner

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!

@quincynyan
Copy link
Author

quincynyan commented Jan 16, 2024

Those are nice new features! I'm writing my own version of neofetch and want to replicate this behavior:



  • Without any offset:
    image

  • With 32px offset from top and 20px offset from left (offset_y variable is 32, offset_x variable is 20)
    image

These behaviors work as intended in w3mimgdisplay (ran using 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.
Is it possible to have options like chafa image.jpb --yoffset 32 --xoffset 20?

PS: btw, the pacman release of chafa hasn't been updated to 1.14.0 yet.

image

@hpjansson
Copy link
Owner

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.

@quincynyan
Copy link
Author

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.

@AnonymouX47
Copy link

AnonymouX47 commented Jan 17, 2024

If I may chime in...

@quincynyan I'm curious, why would column/row offsets not be okay (or even better)?

@quincynyan
Copy link
Author

@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.

@AnonymouX47
Copy link

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.

@hpjansson
Copy link
Owner

@quincynyan Does it have to be absolute offsets? Would it be enough if the current --align center,center centered using pixel offsets, for instance?

@quincynyan
Copy link
Author

@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.

@quincynyan
Copy link
Author

@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
Copy link

@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.

@quincynyan
Copy link
Author

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

@AnonymouX47
Copy link

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:

  1. Such image placements must not be cell-bound in size (which I believe chafa, the library, curently uses for kitty and iterm protocols). Otherwise, it counters the whole point of the offsets.
  2. Some TEs, such as Konsole, do not support sixel transparency but replace with a solid color.
  3. For the iterm protocol (not sure about sixels), the transparent portion of the placed image (used to mimick the offset) would typically replace text content in most TEs... which isn't typically expected behaviour for an offset.
  4. How would this apply to the symbols format?

@quincynyan
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants