3

I need to display an image(bmp) in console window using C++ (Windows 10).

Not display by characters, for that I already knew how, but show the image pixel by pixel the way ordinary images appears to be.

And not by launch another application to show the image in another window, but right in the black console window.

I've searched it all over the internet, but didn't seem to find a way to do it without using things like opencv. Is there a way to do it by myself, without opencv?

beryllium
  • 63
  • 1
  • 1
  • 7
  • 4
    You do know that a console window only displays text right? Also there is no way of doing anything like that using only "C++" as the C++ specification doesn't say anything about loading, decoding or displaying of images of any kind. – Some programmer dude Jul 12 '16 at 07:23
  • [This](http://stackoverflow.com/questions/33538527/display-a-image-in-a-console-application) is a relevant Q&A, albeit in C#, it should give you some hints as the underlying system is of course the same. – Christian.K Jul 12 '16 at 07:23
  • 3
    You might also want to specify what platform/OS/GUI you're using, since most solutions will be non-portable. – Paul R Jul 12 '16 at 07:24
  • 1
    Yes, of course there is. 1. open and read the file. 2. draw the pixels. Where are you stuck? Decoding, color quantization, pixel operations, choice of output character? Thresholding an image and showing a 2 tone representation of it is trivial - decoding the image is far more difficult. Try decoding uncompressed BMP, TGA or TIFF images - their formats are all easily available. – enhzflep Jul 12 '16 at 07:26
  • One question: Why? – Ivan Rubinson Jul 12 '16 at 07:37
  • 1
    the platform is to be put in tag, not title – phuclv Jul 12 '16 at 07:45
  • @enhzflep stuck at "pixel operation"--how can I print a pixel in console window? – beryllium Jul 12 '16 at 07:46
  • @beryllium - just pick a character and use that.Since the text-screen has so few adressable points, the pixels will be huge - 100 times the area of a normal one or so. I just use this character: █ and printf, simple. Consider the following: printf("█ █\n █ █\n"); - a simple 4 square checkerboard.Just draw each scan-line in a loop. Here's something else to think about: https://en.wikipedia.org/wiki/ASCII_art – enhzflep Jul 12 '16 at 08:04
  • 1
    C++ does not have a specific concept of a display. So you need to use some external library. If you want to display something in a terminal (console) then you need to interact with the API of the terminal. So look up the docs for your terminal. – Martin York Mar 21 '20 at 04:43

7 Answers7

3

Your hypothesis is wrong: in general a C++ (or C) program might not even be started from some "console window" (e.g. it might be started in "batch mode"). In particular, some C++ implementations may run on computers (such as Linux servers in data centers, which are the majority of the servers on Internet) without any screen (so without any console window). Most top500 supercomputers don't have screens you could access, but HPC software running on them (e.g. Tripoli-4) is often coded in C++. And embedded computers (e.g. your RaspberryPi) can be programmed in standard C++ (e.g. C++11 or C++14) without any screen or console window (e.g. in 2020 using a recent GCC compiler configured for cross-compilation)

(even on Windows, which I don't know and never used, I am sure that there is some way to start programs -by configuring the computer to start some daemons or servers- before any "console window" exist)

So you should define more precisely what your platform is. In general the answer could be platform and operating system specific. See also OSDEV for examples of open source operating systems: FreeBSD is a famous one, and has a GCC or Clang compiler capable of compiling your C++ application.

I would strongly recommend using a portable graphical framework like Qt (in particular, because it makes your code more portable, if you code carefully). Of course you then requires your user to have it, or your distribute your code with Qt included. Consider also using FLTK or FOX or SFML toolkits.

The C++14 standard (and C++11 and earlier versions) does not know about images or console windows, so (in general, without mentioning any platform or operating system) your question is meaningless.

Study also for inspiration the source code of existing open source programs or libraries coded in C++ (on github or gitlab), such as the fish shell, KDE, GCC, the Clang static analyzer (and they both should be useful to you), RefPerSys, etc etc....

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

You can't do that without using a library.

One way of doing it would be to make your own console window that lets you do that.

I'm not sure if your OS lets you manipulate the console window's pixels.

Ivan Rubinson
  • 3,001
  • 4
  • 19
  • 48
1

A console application can display only text, so you can't draw anything there directly. For draw you need create windows application (in C++, Win32, MFC. or all other language).

1

I was able to display an image in the console using the SetPixel function. You will need to download the EasyBMP library and put it in your visual studio project directory. I used the following code:

#include <windows.h>
#include <iostream>
#include "EasyBMP.h"

void DrwImage(std::string imagePath, HDC* console);
int main() 
{
  //Get current console handle
  HWND console = GetConsoleWindow();
  //Get a handle to console
  HDC dc = GetDC(console);
  // Call DrwImage. It must be a bitmap image
  DrwImage("mybitmap.bmp",&dc);
  return 0;
}
void DrwImage(std::string imagePath, HDC* console) {

   BMP image;
   image.ReadFromFile(imagePath.c_str());
   //image.SetBitDepth(32);
   for (int x = 0; x < image.TellWidth(); x++)
   {
       for (int y = 0; y < image.TellHeight(); y++)
       {
          int RED = image.GetPixel(x, y).Red;
          int GREEN = image.GetPixel(x, y).Green;
          int BLUE = image.GetPixel(x, y).Blue;

          int ALPHA = image.GetPixel(x, y).Alpha;

          COLORREF COLOUR = RGB(RED, GREEN, BLUE);
          if (ALPHA == 0) {
              SetPixel(*console, x, y, COLOUR);
          }
       }
   }
}

I noticed that if you run it in debug mode, it will throw an error but if you run it directly from the command prompt or in a file explorer window it should work fine. I am quite surprised with the result.

enter image description here Note that the drawing of the image on the screen is really slow. For displaying images I recommend using a GUI framework like GTK or wxWidgets. GUI frameworks are well optimized for doing such a task.

0

Oh, simply by looking thru (or reverse engineering) the caca code ;-)

See example use.

hauron
  • 4,550
  • 5
  • 35
  • 52
0

I think I just found what I needed. The SetPixel() function achieves the effect I want.

Though this image is not strictly speaking an "output", but it displayed.

enter image description here

beryllium
  • 63
  • 1
  • 1
  • 7
  • 1
    Just make a proper window program and bitblt the bitmap instead of drawing one pixel at a time on a temporary HDC. – Barmak Shemirani Jul 13 '16 at 09:12
  • `SetPixel` alone doesn't do much, and you didn't post any code to show how you use it. Is the image still displayed if you minimize, then restore, the console window? If not, then this not the right answer. – dxiv Jul 24 '16 at 04:52
0

Check out this project. Here are some examples of showing images in a terminal: Integrating GNUplot to a terminal Integrating ImageMagick to a terminal

drerD
  • 629
  • 1
  • 9
  • 24