How can I read a gray scale JPEG image file in C/C++ into a 2D array?
-
Is the documentation for libjpeg (http://www.ijg.org/) or whatever native API you have inadequate? – greyfade Jan 16 '10 at 07:01
-
3Don't forget to pick a correct answer for the three questions you've asked. – mwcz Jan 20 '10 at 14:33
-
Check this thread out: [read and write image file](http://web.archive.org/web/20080625002549/http://www.dreamincode.net/forums/showtopic29852.htm). Also, have a look at [this other question at Stackoverflow](https://stackoverflow.com/questions/1533542/opencv-cant-read-image). – Lazer Jan 25 '10 at 15:56
6 Answers
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:
- lodepng to read and write png files
- jpeg-compressor to read and write jpeg files

- 3,579
- 1
- 40
- 38
-
2I 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
-
2I 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
-
-
How do I store the result in a 3D array, with the third dimension being the channel? – user3236841 Apr 02 '22 at 02:28
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.

- 494,350
- 52
- 494
- 543
-
2
-
2Since 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
-
1CImg also uses an LGPL-like license which is significantly more restrictive than libjpeg's BSD-like license. – TypeIA Oct 07 '16 at 15:38
-
@Tronic I see it still being maintained https://github.com/boostorg/gil – phuclv Jun 08 '23 at 05:00
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

- 25,006
- 16
- 61
- 78
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.

- 8,949
- 10
- 42
- 63
-
Actually it is modelled as a 4D pixel matrix, though a 2D grayscale image will have the depth and color dimension set to 1. Under the hood it is a 1D array of template type T. – jiggunjer Jun 30 '15 at 15:27
-