stefanhaustein/TerminalImageViewer

ncurses support for the project

MertGunduz opened this issue · 8 comments

Is your feature request related to a problem? Please describe.

Hi @stefanhaustein,


First of all, thanks a lot for creating tiv and this issue is a feature request for for ncurses based TUIs.

I was trying to open images by using tiv in a CLI ncurses-based TUI application.

But whenever I try to open some images with tiv on a ncurses window it doesn't shows the image.

So, in my opinion it would be a great idea to make it also usable in ncurses-based TUIs.

Also, if this sounds like a good idea, I can also work on it. But since the code has no documentation (as far as I know) it is really hard to implement this feature.


Example Code, this will not generate a healthy output.

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>

int main() 
{
    // Initialize ncurses
    initscr();
    cbreak();

    // Check if the terminal supports colors
    if (!has_colors()) 
    {
        fprintf(stdout, "this terminal does not support colors!\n");
        return EXIT_FAILURE;
    }

        start_color();
        init_pair(1, COLOR_BLACK, COLOR_WHITE); // Color for the window
        init_pair(2, COLOR_WHITE, COLOR_BLACK); // Color for the image
        wattron(stdscr, COLOR_PAIR(1));

    // Set up tiv command to display an image
    char *imageFile = "a92c5191f11b0e544f276011e898294f.png"; // Replace with your image file path
    char tivCommand[256];
    snprintf(tivCommand, sizeof(tivCommand), "tiv %s", imageFile);

    // Display the image using tiv
    system(tivCommand);
    refresh();

    // Wait for a key to close the TUI
    getch();

    // Clean up
    endwin();

    return 0;
}

Describe the solution you'd like

Creating a .h file

There is a solution we can use, creating a small .h file to handle this problems.

And by doing this, we could actually create a big revolution in the TUI history. It was always a big problem to put functional images to terminals.

Some of the ncurses headers:


<form.h>: Header file for working with forms in ncurses, which allows you to create interactive forms.

<menu.h>: Header file for creating menus in ncurses.

<panel.h>: Header file for using panels in ncurses, which allows you to manage overlapping windows.

<term.h>: Header file for terminal-related definitions and functions.

For example, we can implement our .h file like tiv.h (for normal output) and tivcurses.h (four ncurses output) to use it as a library.

Describe alternatives you've considered

Adding a new option

Also, writing a new option to tiv (terminal-image-viewer) can be helpful.

tiv --ncurses .*png

For example, by using the above command we can show them in a new window by using ncurses.

It will open a window in ncurses and list the images by using tiv, it will not output to stdout. Instead it will output to the stdscr or specified screen.

Additional context

Support

I can support the project by contributing the features and improving the current code by making it more readable.

Also doxygen or any kind of documenting tool would be helpful for other devs.

But whenever I try to open some images with tiv on a ncurses window it doesn't shows the image.

What happens?

Other than the "adding a new option" and better documentation I'm not exactly sure what this means, does specifying the width and height (#37 basically) solve the issue?

Are you recommending the program have easily usable output? If so that might be #52.

P.S.: I've read the code before and quit soon after trying to read emit_image where the action happen. That was some years ago though, and my skills have improved since then. I'll see if I can add some Doxygen.

Error

When I run the code the ncurses TUI opens and I can't see the tiv image output. After closing my TUI app it turns to my normal terminal and shows me the image in a corrupted way. I want tiv to output it to ncurses based TUI, so we have to output tiv to the stdscr or any ncurses-based window.

Also giving a set width doesn't helps with it. I set the width to 32 but didn't helped me to fix the issue.


1 -> running the executable (no image) [NCURSES BASED TUI]

First it opens the ncurses TUI and shows nothing, probably tiv outputs to stdout:
image

2 -> closing the executable (corrupted image) [NORMAL TERMINAL]

After the ncurses based TUI app finishes, this happens on the normal terminal:
image

Also, about the documentation I meant making the code more readable and modular by using doxygen-like commenting and placing the codes and functions to seperate files.

If I could read the code I would handle this task but it is a very long code and nearly impossible to implement the feature with this way.

And if possible, could you give me some information about the code. What's the Java part do and C++ do?

This project used to be coded in Java. Due to how slow that was for such simple tasks Stefan rewrote the project in C++. Currently only the C++ part matters and the Java implementation is deprecated. I understand what you mean about the documentation.

I think what's happening is that ncurses isn't capturing the output. All you did was run the tiv command, which ran in the background.

This project used to be coded in Java. Due to how slow that was for such simple tasks Stefan rewrote the project in C++. Currently only the C++ part matters and the Java implementation is deprecated. I understand what you mean about the documentation.

I think what's happening is that ncurses isn't capturing the output. All you did was run the tiv command, which ran in the background.

I got it, thanks a lot. Do you think is there a way to output it to a ncurses window?

https://stackoverflow.com/questions/41884266/system-output-in-ncurses says

The popen() function can be used to execute a command and to read its output programatically.

https://stackoverflow.com/questions/41884266/system-output-in-ncurses says

The popen() function can be used to execute a command and to read its output programatically.

I've tried it doing with popen function, it gives me the ansi escape codes directly but I can't process them in ncurses terminal. Probably ncurses can't interprete the ANSI Escape Codes.

So I have to process them directly and output them in ncurses. This is at least a solution for my case.

Example ANSI Escape Code: ^[[48;2;23;19;16m


The code I've tried:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>

int main() 
{
    initscr();
    cbreak();
    noecho();
    curs_set(0);
    keypad(stdscr, TRUE);

    FILE *pipe = popen("tiv -w 16 photo-1608848461950-0fe51dfc41cb.jpeg", "r");
    char buffer[2048];

    while (fgets(buffer, 2047, pipe) != NULL)
    {
        for (int i = 0; i < strlen(buffer); i++)
        {
            printw("%s", buffer);
        }
        getch();
    }

    getch();
    endwin();
    return 0;
}

Output:

Screenshot from 2023-09-10 04-57-55

Well, the only solution to that on our end I can think of is to separate tiv into a library. Great to hear that it worked.