[HN Gopher] Show HN: a Rust based CLI tool 'imgcatr' for display...
___________________________________________________________________
Show HN: a Rust based CLI tool 'imgcatr' for displaying images
cat for images, by RUST
Author : cheeseisinsane
Score : 116 points
Date : 2024-04-16 08:30 UTC (14 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| TazeTSchnitzel wrote:
| You could get better resolution in some terminals by using
| sixels: https://en.wikipedia.org/wiki/Sixel
|
| I think there's some other methods in particular terminals for
| displaying images, but I don't remember them.
| warbled_tongue wrote:
| Yeah, but this is in rust.
| ramon156 wrote:
| Huh?
| martijnarts wrote:
| You could also probably detect the terminal you're in and use
| some of their advanced features, like the image protocol in
| iTerm2[0] or the terminal graphics protocol[1]. 1 also lists
| alternative programs that do this!
|
| [0]: https://iterm2.com/documentation-images.html [1]:
| https://sw.kovidgoyal.net/kitty/graphics-protocol/
| hnlmorg wrote:
| This is how murex works too https://github.com/lmorg/murex/bl
| ob/master/config/defaults/p...
| dale_glass wrote:
| And kitty has icat, which just has image support:
| https://sw.kovidgoyal.net/kitty/kittens/icat/
|
| I'm really confused about how is it that we're in 2024, Linux
| is open source from top to bottom, and we're still messing
| around with rendering images in ASCII.
|
| I really wish there was some interest in doing a modern,
| graphical console. UTF8, antialiasing, graphics, the works.
| eptcyka wrote:
| X is literally that.
| mxuribe wrote:
| Would you kindly clarify? Did you mean Xterm?
| Tmpod wrote:
| I believe they meant X.org, the graphical stack used by
| most graphical Linux systems.
| baq wrote:
| > modern
|
| um.
|
| I guess the rest applies, but...
| IshKebab wrote:
| It's not though. You have to fiddle around with ports and
| servers and environment variables.
|
| But a drawing API is clearly not the way modern graphics
| works best. What would be really cool is a terminal that
| supported low latency streaming video. Then you can do
| proper GUI apps using any rendering system they want and it
| will properly integrate with ssh.
| ranger_danger wrote:
| Xsixel
| hnlmorg wrote:
| I'm working on exactly that :)
| lambdaba wrote:
| On behalf of the entire console user community, thank you!
| exitb wrote:
| I have a feeling that we'd end up regretting it. It would get
| abused in all the unnecessary ways. Kind of like the magic
| Docker outputs, with output previews and multiple progress
| bars that break into a horrible mess the moment they hit a
| log file, instead of a terminal.
| ranger_danger wrote:
| Most new-age terminal emulators do have image support and
| more are getting support every day, even Windows Terminal is
| working on it.
|
| However this brings up the philosophical debate of just how
| close you're becoming to a real window manager or display
| server in the first place.
| pwdisswordfishc wrote:
| TermKit?
| godelski wrote:
| Kitty is fine, but there is a big issue with tmux and the dev
| seems to think it is about tiling and not about using remote
| machines.[0] Sure, I tile because it is there and I don't
| have control of the terminal I'll use on the other end, but
| the main draw is I gotta work on machines I'm connecting to
| with ssh. I think there's a lot of us still needing tools
| like this (and mosh) but little support. Looks like people
| were trying to help the dev but there was communication
| breakdown. I'm all for making sure things are done right and
| not just accepting hacky solutions, but there has to end up
| being a solution.
|
| I'd honestly just love to have a minimal terminal like
| foot[1], but that's wayland only and wayland support is still
| very mixed. And who knows when ghostty will come out[2]. But
| I also need linux + mac support and I think a lot of people
| do (and no wayland to mac port?). Too many terminals are far
| too bloated. And boy... do I not need this bullshit[3]
|
| [0] https://github.com/kovidgoyal/kitty/issues/391
|
| [1] https://codeberg.org/dnkl/foot
|
| [2] https://mitchellh.com/ghostty
|
| [3] https://github.com/warpdotdev/Warp/issues/900
| berkes wrote:
| I do a lot of work in the terminal. And every few weeks I'm
| wishing for something like "cat for images".
|
| "I should write it!". And then realize it already exists and is
| on my machine. I presume most OSes and distro's have some simple
| image viewer. Mine, Ubuntu, comes with `eog`.
|
| Very rarely, am I on a machine that has no display, and I still
| need to view some images that live there. Then the workflow
| becomes convoluted: transfer images to a local machine, or put
| them in some http-accessible place. For those cases, I think
| imgcatr would be great. But then it's not available on these
| machines, so that kindof defeats the purpose again.
| e12e wrote:
| > Very rarely, am I on a machine that has no display, and I
| still need to view some images that live there.
|
| X11 forwarding over ssh is an option.
| elliottcarlson wrote:
| I was making a similar library (paired with a cli app) in Go a
| while back with some fun results -- it lead me down a rabbit hole
| trying to render animated gifs, which has interesting results
| depending on the terminal being used. I also implemented the
| resizing of the images to properly scale for the terminal as
| well. I never actually got around to uploading the repo, but will
| try to get around to that tonight.
|
| Some videos of it in action: https://youtu.be/L2LTPKW6EPw
| https://youtu.be/b0CYZyuKLr8 https://youtu.be/_VnV96l5Xkc
| overcrowd8537 wrote:
| I also did something in dotnet that was a half baked visual
| media player. Had seek, pause, dynamic resizing, and a frame
| buffer all implemented, but it was a super naive
| representation. It was neat to be able to save frames of a
| movie as ascii text to a text file with or without ansi escape
| sequences to even view later on a machine without the app.
| hsfzxjy wrote:
| I've made one years ago, supporting gif
|
| https://github.com/hsfzxjy/i2a-rs
| plasticeagle wrote:
| It doesn't seem to work in macos terminal, but it's likely my
| term environment vars aren't set correctly.
|
| I just get a whole pile of random colour, some of which are
| flashing.
| capitainenemo wrote:
| IMO the best results out there are with chafa right now.
| https://hpjansson.org/chafa/gallery/
|
| It also has some basic ffmpeg support.
|
| And yeah, there are sixels and native rendering of graphics in
| terminals, but I still find this handy if I'm a couple of tmux
| sessions deep on a remote server and I need to figure out which
| graphic is which.
| kernelsanderz wrote:
| I just noticed that tmux has some basic sixel support now -
| https://raw.githubusercontent.com/tmux/tmux/3.4/CHANGES
|
| discovered at https://www.arewesixelyet.com/
| capitainenemo wrote:
| I guess it'll take a while for that to propagate. I wonder
| how well it works with nested tmux sessions and multiple
| servers. Also I do have the issue with terminals support.
| Regrettably the assigned work computer is still Windows, and
| I've been using putty there. If you know of a good sixel
| terminal for windows..
|
| Anyway, Chafa's results are darn good IMO. The images in the
| gallery don't I feel showcase how well it matches against
| organic forms. And it handles a wide variety of images. SVG
| etc.
|
| Even when I have access to pixels, I find on slow connections
| Chafa can be a decent form of compression :) For example, I
| was using the ffmpeg patch to play a video remotely to figure
| out what it was and while I could have relayed it with ssh
| -YC , Chafa was simply a lot more performant due to it being
| a lossy transformation. Kinda like playing the video in a VNC
| session with jpeg loss cranked up to max, but without the
| need to fire that up.
| williamcotton wrote:
| If you're on MacOS an imgcat tool pairs well with an imgpbcopy
| tool like this:
|
| https://github.com/williamcotton/dotfiles/blob/master/bin/im...
|
| Then create a shell function like: imgc() {
| tee >(imgcat "$@") >(impbcopy -) > /dev/null }
|
| So you can: cat image.png | imgc
|
| Which will then show the image in the console, and if you switch
| over to another app you can simply paste in the image. And if you
| create a new file in Preview it will be the image in the paste
| buffer!
| throwaway143829 wrote:
| What's the difference between this recipe and `impbcopy
| image.png`? Is it just for the pixelated effect?
| williamcotton wrote:
| I use: https://pypi.org/project/imgcat/
|
| The VS Code terminal supports both the sixel and iterm image
| format so you get the actual image.
|
| Most of the time I'm using it with my personal CLI graph
| template language: cat some.csv | plt '[x,
| y], z { bar 10px [solid red, solid green] }' | imgc
|
| So then I see the graph in the console and then I'm ready to
| save it if I'm happy with the output.
|
| If you're curious, here's plt, powered by python and
| matplotlib under the hood: https://github.com/williamcotton/d
| otfiles/blob/master/bin/pl...
| godelski wrote:
| Strangely this doesn't work inside tmux...
|
| It really seems like there are a lot of issues with
| rendering images in the cli. I know kitty has a python
| version too but kitty doesn't play nice with tmux and the
| dev isn't a fan of tmux[0]. To be fair, I'd love to move
| away from tmux but I use remote machines all day and I
| haven't found a good alternative. I don't care about tiling
| (I can do that in vim, even the terminal), though it is
| useful (mostly switching sessions for managing workflow
| context). I'd also love to see someone pick back up mosh
| (ssh).
|
| A critical problem is that if you work on remote machines a
| lot you probably gotta be able to build some things from
| source and build into your local bin because you don't have
| sudo access on the machine. Preferably installs without
| network access.
|
| [0] https://github.com/kovidgoyal/kitty/issues/391
| tempay wrote:
| On macOS iterm2 has really nice integration with tmux[1]
| via tmux's "Control Mode". It allows you to use tmux
| almost transparently including image printing, mapping
| windows/split panes into tabs/native splits.
|
| [1] https://iterm2.com/documentation-one-
| page.html#documentation...
| emilsayahi wrote:
| I tried this two years ago when I was still actively 'learning'
| Rust: https://github.com/Dirout/depi
| wokwokwok wrote:
| > cargo install imgcatr
|
| I feel very uncomfortable seeing cargo being used as a tool to
| distribute software.
|
| Cargo is a package manager.
|
| It should build software.
|
| I suppose it's arguable that it should be able to install
| developer tooling to help you build things.
|
| However, I feel uncomfortable seeing this type of thing.
|
| Is the installed binary sandboxed? It is namespaced? Is it shared
| between projects? What causes it to be updated?
|
| Can building a crate update the globally installed version of
| "foo" by "cargo install" installing a different crate that
| happens to have a binary with the same name? (Yes, via build.rs,
| but just as a dependency?)
|
| How would I even know?
|
| There are so many things wrong with this imo.
|
| Building a crate should generally be sandboxed, but this (cargo
| install as a concept, not this particular app) feels like the
| goal is the _opposite_ of a sandbox, instead it's a shared
| arbitrary named tool that goes into your path by default and gets
| updated an unknown times.
|
| I feel like this is going to bite the rust community in the foot
| at some point.
| onei wrote:
| The go CLI does exactly the same. Python's pip (via setup.py)
| will do the same, and in an arguably less transparent way iirc.
| I don't disagree that there are better ways, but it's good
| enough to get you off the ground.
| lelandbatey wrote:
| To clarify, cargo is like pip _but pip with the --user flag
| on by default_.
| gpm wrote:
| `pip --user` still installs things to a per-user-global
| shared folder, that doesn't exist with cargo. If you're
| going to compare to pip, it's got to be something like
| "pip, but everything you build gets its own venv".
| nicce wrote:
| If you install binary blob from the internet, you trust exactly
| one person and no way to verify if binary matches the source.
|
| If you build with cargo, you can at least verify that the
| current source matches the binary and the trust of the
| dependencies is decentralized, with many eyes on them.
|
| There are better ways, but these better ways just use different
| package managers. The above is no different than any "build
| from source" method.
| tester457 wrote:
| > Is the installed binary sandboxed? It is namespaced?
|
| I write dumb simple cli tools for myself. How to do either of
| these things?
| wokwokwok wrote:
| By only allowing it to be on the PATH when you're in a
| specific folder (eg. The binary only ever lives in
| project/bin, not $user/.shared/bin) and by making the binary
| filename have a prefix (eg. project-git) so you can't
| possibly invoke it when expecting to call a normal cli
| command (eg git).
|
| Since cargo manages these installs, both would be trivial for
| it to do; just inconvenient for cli app authors.
| semi-extrinsic wrote:
| But this is not "sandboxed" in any conventional
| understanding of the term. "sandboxed" would mean that the
| binary has restricted access to resources like the
| filesystem, the network etc.
| gpm wrote:
| I think you're fundamentally misunderstanding what is going on
| here, because your questions about "namespacing", "being shared
| between objects", and "building installing things" suggest your
| imagining a system that doesn't exist here. Cargo, unlike a
| system like pip, doesn't have global files*, it doesn't have
| libraries installed to the system, there is no* global state to
| corrupt.
|
| The only "side effect" of running a `cargo install` command is
| that a binary is placed in `~/.cargo/bin`, which most rust
| programmers will have on their PATH. There are no side effects
| of running a normal cargo build, it won't update anything
| outside of the crate you are building (and in the crate you are
| building, it will only change Cargo.lock and the target
| directory). There isn't any scary action at a distance.
|
| > What causes it to be updated?
|
| Nothing, except a user manually running `cargo install --force
| imgcatr`. This is the main criticism of using `cargo install`,
| it's not a package manager, it's a shortcut to doing the C
| equivalent of `git clone project && cd project && ./configure
| --prefix=~/.cargo/bin && make && make install` (but for
| binaries only, no libraries).
|
| * There is a local cache of checked out code, and the index of
| crates, which is generally updated every time you run a `cargo
| build` command that might need anything that isn't local. You
| can use this cache without touching the internet by specifying
| `--offline`, at which point the contents of the cache matters.
| The only reason to do this is if you don't have internet. I'm
| also ignoring nonsense that people can put in `build.rs` files,
| but pretty much no one does. Rust will also look for certain
| global dependencies on your system (namely C style libraries),
| but it doesn't have any support for putting new ones there.
| wokwokwok wrote:
| > command is that a binary is placed in `~/.cargo/bin`, which
| most rust programmers will have on their PATH
|
| That is a global effect.
|
| > Nothing, except a user manually running `cargo install
| --force imgcatr`.
|
| I'm absolutely certain build.rs can also do this; you can
| choose to ignore that if you want.
|
| I hope ignoring it makes it not a thing we have to ever worry
| about. I guess.
|
| I get it, it's convenient; but I think people are fooling
| themselves if they think having a binary on their path is no
| big deal, or that manually calling "cargo install" is the
| only way this can happen.
|
| FWIW, there is a precedent with serde shipping a binary
| (https://github.com/serde-rs/serde/releases/tag/v1.0.184
| related discussion etc. which kind of shows this is not an
| idle concern)... mmm... oh well, whatever I guess.
| gpm wrote:
| > That is a global effect.
|
| Yes, I agree, that's why I said it is the _only_ one.
| Moreover the sole purpose of cargo install is to cause that
| side effect (otherwise you use cargo build, which builds
| the binaries but doesn 't copy them to a shared directory).
|
| > I'm absolutely certain build.rs can also do this
|
| build.rs is running arbitrary code, it _can_ do anything,
| that 's part of what I disclaimed in my asterix. In
| practice it _doesn 't_ do anything. Every packaging system
| has an escape hatch like this.
|
| Serde shipping a binary was someone embedding a chunk of
| opaque bytes in their "source code", it's completely
| unrelated to this discussion and has no effect on what
| `cargo install` does.
| woodrowbarlow wrote:
| > I feel very uncomfortable seeing cargo being used as a tool
| to distribute software. Cargo is a package manager.
|
| but... that's exactly what a package manager is. a tool to
| package and distribute software. apt, dnf, nix, snap, flatpak,
| npm, cargo, pip... they're all package managers.
| earthling8118 wrote:
| I think their thought was incomplete. It's a language-
| specific package manager. Out of that list I think there are
| some that have no business installing packages for use on the
| greater system. They work fine for development dependencies
| and project building, but they should stay in their lane when
| it comes to installing tools to use outside of project
| development.
| woodrowbarlow wrote:
| oh, that makes sense. it just means the packaging hasn't
| been taken as far as it can go. once a project is set up
| for packaging using something like `cargo`, that means it
| will be that much easier for someone (anyone) to take it
| one step further and package it in higher-level package
| managers like `apt` or `dnf` on top. or `snap` or
| `flatpak`. or a nix/arch recipe.
| S0y wrote:
| I loved those image2text ever since I learned about libcaca
| http://caca.zoy.org/wiki/libcaca
| timetraveller26 wrote:
| If you use the kitty terminal you can use:
|
| kitten icat image.jpeg
| cameroncooper wrote:
| Terminology (part of Enlightenment) is a fantastic terminal and
| has image support.
|
| https://www.enlightenment.org/about-terminology.md
| semi-extrinsic wrote:
| Ah, Enlightenment, that's a blast from the past! I remember
| using a heavily riced E16 back in the days. I haven't tried it
| after I fell into the tiling WM rabbit hole 15 years ago. How
| is it holding up?
| Fileformat wrote:
| timg is a really nice similar tool that does pixel graphics in
| the terminal window if supported, falling back to character
| graphics if not.
|
| The big plus is that it supports SVG images.
|
| https://github.com/hzeller/timg
|
| And it is available via brew/apt/etc.
| zamubafoo wrote:
| While not CLI, I always look for cross platform image viewers and
| found https://github.com/woelper/oculante.
|
| Had a few woes compiling it due to my laptops configuration, but
| once compiled it works with everything I would reasonably throw
| at it.
| m0shen wrote:
| I love seeing how many people wrote one of these. I've written 2:
|
| One to learn golang that plays gifs -
| https://github.com/moshen/gotermimg
|
| And one in perl - https://github.com/moshen/Image-Term256Color
| skyfaller wrote:
| I've been using viu, which is also written in Rust:
| https://github.com/atanunq/viu
|
| How does imgcatr compare?
|
| Viu was last updated 5 months ago, imgcatr 3 months ago, not a
| significant difference. imgcatr is a longer name than viu,
| requiring more keystrokes to type.
___________________________________________________________________
(page generated 2024-04-16 23:01 UTC)