Has my motd gone too far? It loads a random ANSI catgirl from a folder. I use arch btw, server runs minimized Ubuntu Server.

all 27 comments

sorted by: hot top controversial new old
[–] 52 points 1 year ago (9 children)

You could double the vertical resolution by using half-height blocks (U+2584) and using the background color for the upper half.

  • source
  • hideshow 9 child comments
  • [–] [S] 19 points 1 year ago (8 children)

    Thanks for the suggestion, gonna look into this. I didn't want to use real images even though kitty supports them because I like the retro look and wanted it terminal agnostic for when I use termux on my phone.

  • source
  • parent
  • hideshow 8 child comments
  • [–] 20 points 1 year ago* (last edited 1 year ago) (7 children)

    I gladly present you this jank.

    You might need these to compile:

    cargo add image
    cargo add clap --features derive
    

    And the jank itself:

    Some Rust code

    use std::path::PathBuf;
    
    use clap::Parser;
    use image::{ imageops::{self, FilterType}, ImageReader };
    
    #[derive(Parser)]
    struct Cli {
        path: PathBuf,
        #[arg(short = 'H', long, default_value_t = 30)]
        height: u32,
        #[arg(short, long, default_value_t = 0.4)]
        ratio: f32,
        #[arg(short, long, default_value_t, value_enum)]
        filter: Filter,
    }
    
    #[derive(clap::ValueEnum, Clone, Default)]
    enum Filter {
        Nearest,
        Triangle,
        Gaussian,
        CatmullRom,
        #[default]
        Lanczos3,
    }
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let args = Cli::parse();
        let filter = match args.filter {
            Filter::Nearest    => { FilterType::Nearest },
            Filter::Triangle   => { FilterType::Triangle },
            Filter::CatmullRom => { FilterType::CatmullRom },
            Filter::Gaussian   => { FilterType::Gaussian },
            Filter::Lanczos3   => { FilterType::Lanczos3 },
        };
        let img = ImageReader::open(args.path)?.decode()?;
        let original_ratio = img.width() as f32 / img.height() as f32;
        let width = ( args.height as f32 / args.ratio ) * original_ratio;
        let out = imageops::resize(&img, width as u32, args.height * 2, filter);
        let mut iter = out.enumerate_rows();
        while let Some((_, top)) = iter.next() {
            let (_, bottom) = iter.next().unwrap();
            top.zip(bottom)
                .for_each(|((_, _, t), (_, _, b))| {
                    print!("\x1B[38;2;{};{};{};48;2;{};{};{}m\u{2584}", b[0], b[1], b[2], t[0], t[1], t[2])
                });
            println!("\x1B[0m");
        }
        Ok(())
    }
    

  • source
  • parent
  • hideshow 7 child comments
  • [–] [S] 9 points 1 year ago (1 child)

    It's beautiful! I actually adjusted my python code to your method and just for optimization checked if the current two pixel colors match the previous two and if so leave out the color info. Much more fidelity in the images now!

  • source
  • parent
  • hideshow 1 child comment
  • As an extra optimization, if top and bottom colors of a pixel match, you can just output space and only set background color. Implemented correctly, this can save a lot of memory. Didn't want to make the code more complex in fear of people being scared of running it.

  • source
  • parent
  • [–] 5 points 1 year ago* (last edited 1 year ago) (4 children)

    I've been learning Rust by going through The Book... there's some wack-ass syntax in that language. I've mostly used C# and Python so most of it just looks weird... I can more or less understand what while let Some((_, top)) = iter.next() { ... } is doing, but .for_each(|((_, _, t), (_, _, b))| { ... } just looks like an abomination. And I mean the syntax in general, not this code in particular.

  • source
  • parent
  • hideshow 4 child comments
  • [–] 7 points 1 year ago (2 children)

    but .for_each(|((_, , t), (, _, b))| { ... } just looks like an abomination

    It's not so different in python: for ((_, _, t), (_, _, b)) in zip(top, bottom):

    Or in C#: .ForEach(((_, _, t), (_, _, b)) => Console.Write(...));

  • source
  • parent
  • hideshow 2 child comments
  • [–] 3 points 1 year ago* (last edited 1 year ago)
    .for_each(|((_, _, t), (_, _, b))| { ... }
    

    This is actually fairly similar to what C# has.

    This is a closure syntax:

    | arguments | { calls }
    

    In C#, the closest is lambda expressions, declared like this:

    ( arguments ) => { calls }
    

    Parentheses are tuple deconstructors. In C# you have exactly the same thing. Imagine you have a method that returns a two element tuple. If you do this:

    var (one, two) = MethodThatReturnsATuple();
    

    You'll get your tuple broken down automatically and variables one and two declared for you.

    First of all, I'm using .zip() to pair the rows of the picture by two, that returns a tuple, so, I have to deconstruct that. That's what the outer parentheses are for. The pixel enumeration stuff I'm using returns a tuple (u32, u32, &Rgba<u8>) first two values are x and y of the pixel, the third one is a reference to a structure with color data. I deconstruct those and just discard the position of the pixel, you do that with an underscore, same as C#.

    I'm not that far into learning myself, but I'm not a textbook learner at all. Poking around opensource projects and wrestling with the compiler prooved to educate me a lot more.

  • source
  • parent
  • [–] 40 points 1 year ago

    Catgirls aren't cringe, but ubuntu is.

  • source
  • [–] 34 points 1 year ago

    It would be cringe if you were using a shared server and set this as a default for everyone or if it was interfering with something. But if you're just minding your own business I could not care less what customisations you put on your terminal as long as it isn't using excessive resources

  • source
  • [–] 42 points 1 year ago (2 children)

    The real cringe is using passwords instead of keys to login.

  • source
  • hideshow 2 child comments
  • [–] 11 points 1 year ago (1 child)

    Never too far, also can you share how you did that?

  • source
  • hideshow 1 child comment
  • [–] 8 points 1 year ago (1 child)

    Needs more pixels. You use Kitty, try something like https://github.com/hpjansson/chafa to render a proper picture?

  • source
  • hideshow 1 child comment
  • [–] 12 points 1 year ago

    I can't hate on ANSI art even if I'm not in to what the art is of. 🀷

  • source
  • [–] 9 points 1 year ago

    Nah, I don't think so. I mean, sure, arch is a little cringe, but it's not that bad. Cool terminal, btw.

  • source
  • [–] 4 points 1 year ago

    How??? Asking for a friend...

  • source
  • [–] 3 points 1 year ago

    Okaerinasaimase, goshujinsama

  • source
  • [–] 3 points 1 year ago (2 children)

    I thought motd could not be scripted hmmm...

  • source
  • hideshow 2 child comments