28

I need to read an image file in C/C++. It would be very great, if some one can post the code for me.

I work on gray scale images and the images are JPEG. I would like to read the images into a 2D array which will make my work easy.

A-Sharabiani
  • 15,608
  • 15
  • 99
  • 122
skyrulz
  • 357
  • 1
  • 5
  • 6

7 Answers7

23

If you decide to go for a minimal approach, without libpng/libjpeg dependencies, I suggest using stb_image and stb_image_write, found here.

It's as simple as it gets, you just need to place the header files stb_image.h and stb_image_write.h in your folder.

Here's the code that you need to read images:

#include <stdint.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int main() {
    int width, height, bpp;

    uint8_t* rgb_image = stbi_load("image.png", &width, &height, &bpp, 3);

    stbi_image_free(rgb_image);

    return 0;
}

And here's the code to write an image:

#include <stdint.h>

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#define CHANNEL_NUM 3

int main() {
    int width = 800; 
    int height = 800;

    uint8_t* rgb_image;
    rgb_image = malloc(width*height*CHANNEL_NUM);

    // Write your code to populate rgb_image here

    stbi_write_png("image.png", width, height, CHANNEL_NUM, rgb_image, width*CHANNEL_NUM);

    return 0;
}

You can compile without flags or dependencies:

g++ main.cpp

Other lightweight alternatives include:

Jaime Ivan Cervantes
  • 3,441
  • 1
  • 36
  • 36
  • 2
    I had to include the math.h library and link it while compiling (http://stackoverflow.com/questions/8671366/undefined-reference-to-pow-and-floor) or I would get an undefined reference to pow in the image library. – Ste_95 Feb 08 '17 at 16:03
  • 2
    I know it's just an example but can you clarify what the magic number 3 means in the code? – mattshu Jan 24 '18 at 04:56
  • 2
    @mattshu it's the number of channels (red, green, blue), maybe I should clarify this on my code, I'll do a edit. – Jaime Ivan Cervantes Jan 25 '18 at 02:41
  • How would I do something like this WITHOUT any odd libraries? I am not the author of the question, but I want to know how to this only using standard libraries like stdio.h Actually, how to do this ONLY using stdio.h? –  Jan 16 '20 at 17:32
  • STB developers ain't good. – ayesbee Oct 20 '20 at 10:23
  • How do I store the result in a 3D array, with the third dimension being the channel? – user3236841 Apr 02 '22 at 02:28
15

You could write your own by looking at the JPEG format.

That said, try a pre-existing library like CImg, or Boost's GIL. Or for strictly JPEG's, libjpeg. There is also the CxImage class on CodeProject.

Here's a big list.

GManNickG
  • 478,574
  • 51
  • 478
  • 539
  • 2
    Boost.GIL does not work and is not being maintained. – Tronic Jan 25 '10 at 15:59
  • 2
    Since C is allowed, I second libjpeg as the most lightweight solution. CImg and GIL are definitely easier syntax-wise--but also require libjpeg. You can trivially copy the data from a CImg object into some STL container or an array. – jiggunjer Jun 30 '15 at 15:24
  • 1
    CImg also uses an LGPL-like license which is significantly more restrictive than libjpeg's BSD-like license. – TypeIA Oct 07 '16 at 15:38
4

Check out Intel Open CV library ...

Ashish
  • 8,059
  • 11
  • 51
  • 92
4

Check this thread out: read and write image file.

Also, have a look at this other question at Stackoverflow.

Community
  • 1
  • 1
Lazer
  • 85,489
  • 111
  • 272
  • 354
3

corona is nice. From the tutorial:

corona::Image* image = corona::OpenImage("img.jpg", corona::PF_R8G8B8A8);
if (!image) {
  // error!
}

int width  = image->getWidth();
int height = image->getHeight();
void* pixels = image->getPixels();

// we're guaranteed that the first eight bits of every pixel is red,
// the next eight bits is green, and so on...
typedef unsigned char byte;
byte* p = (byte*)pixels;
for (int i = 0; i < width * height; ++i) {
  byte red   = *p++;
  byte green = *p++;
  byte blue  = *p++;
  byte alpha = *p++;
}

pixels would be a one dimensional array, but you could easily convert a given x and y position to a position in a 1D array. Something like pos = (y * width) + x

Firas Assaad
  • 23,880
  • 16
  • 59
  • 78
2

Try out the CImg library. The tutorial will help you get familiarized. Once you have a CImg object, the data() function will give you access to the 2D pixel buffer array.

mwcz
  • 8,310
  • 9
  • 40
  • 63
1

Check out the Magick++ API to ImageMagick.

R Samuel Klatchko
  • 72,827
  • 15
  • 131
  • 185