1

How to read an image in C++ as a 2D array? I need to create a C/C++ program that reads an image (all formats) as a 2D array to show pixel values (0-255), divide the image into blocks and apply different compression methods using pixels blocks (BTC, AMBTC, MMBTC) and saving the new image by hand without using already set libraries (must not use magic++).. thanks in advance

Hajar Alhalabi
  • 303
  • 1
  • 2
  • 9
  • 2
    Depends on the image format, the platform, your compiler, and many other things. Can you be a bit more specific? – Adrian Mole Jan 02 '20 at 09:24
  • Does this answer your question? [Reading an image file in C/C++](https://stackoverflow.com/questions/2076475/reading-an-image-file-in-c-c) – TruthSeeker Jan 02 '20 at 09:24
  • Take a look at this https://stackoverflow.com/questions/33780943/read-an-image-or-pdf-using-c-without-external-library – MeiH Jan 02 '20 at 09:24
  • This is easiest... https://stackoverflow.com/a/33777883/2836621 – Mark Setchell Jan 02 '20 at 09:28
  • Adrian Mole ..I use VS 2017 on Windows 10 .. no specific image format so if I could create a program that works on all formats it would be perfect, if not JPEG is a good start ..thank you – Hajar Alhalabi Jan 02 '20 at 10:17
  • 1
    @HajarAlhalabi If you are comfortable with using `MFC` then the `CImage` class is your best pal: it can read all the standard formats (GIF, JPEG, TIFF, BMP, &c) and has member functions that make it *relatively* easy to get access to the raw pixel buffer. I can give you some sample code, if that's a direction you're happy to take. – Adrian Mole Jan 02 '20 at 11:09
  • 1
    @Close-Voter: OP is *not* looking for a library or off-site resource, *per se*. In fact they state: "without using already set libraries!" – Adrian Mole Jan 02 '20 at 11:19
  • @AdrianMole my next step is working on the interfaces of the program so the MFC would be perfect.. I would appreciate it if you gave me a sample code..many thanks – Hajar Alhalabi Jan 02 '20 at 11:56

1 Answers1

1

Here's some 'outline' code using MFC's CImage class that may help you. I've shown how to use the basic Load and Save options, and how to get a 'raw' array of pixel data (note: it's best to convert to 32-bit format, so you can be sure the DWORD pointer you get will really be to a width X height array - other BPP formats can give strange results):

First, load from file (CImage will know or guess the format from the file extension):

CImage original;
original.Load("Yourfile.jpg"); // Use actual file path, obviously 

int pw = original.GetWidth(), ph = original.GetHeight(); // Dimensions
CImage working; // Use this to hold our 32-bit image
working.Create(pw, ph, 32);

// Next, copy image from original to working...
HDC hDC = working.GetDC();
original.BitBlt(hDC, 0, 0, SRCCOPY);
working.ReleaseDC();

// Get a DWORD pointer to the pixel data...
BITMAP bmp;
GetObject(working.operator HBITMAP(), sizeof(BITMAP), &bmp);
DWORD* pixbuf = static_cast<DWORD*>(bmp.bmBits);
// We can now access any pixel(x,y) data using: pixbuf[x + y * pw]

You now do all sorts of work on your image buffer, using the pixbuf array, as stated in the comment. For clarity: each DWORD (32-bit unsigned) in the buffer will be the RGBA data (where A is the 'alpha` channel - set to zero) but in reversed order; so, for each DWORD, the bytes will be 0xBBBBGGGGRRRR0000.

When you're done, you can save your modified image as follows:

CImage savepic;
savepic.Create(pw, ph, 24); // Change 24 to whatever BPP you require
hDC = savepic.GetDC();
working.BitBlt(hDC, 0, 0, SRCCOPY); // Copies modified image to output
savepic.ReleaseDC();
savepic.Save("NewFile.jpg"); // CImage understand what format to use base on extension

Of course, in a real-world program, there are error checks that you will need to make (most CImage methods return a status indicator, and GetLastError() can be used), and you would probably be safer copying the 'pixbuf' data to a separate memory zone - but, hopefully, this brief outline will help you get started.

Feel free to ask for further clarification and/or explanation.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83