get pixel color values from image.png

1. how can i link to an image that's on desktop?
write a path to it or include it into my project somehow?
2. how to get rgb values from a pixel of that image?
1. As with any file, you need to open it either using a path relative to your program's working directory, or an absolute path.
For example (assuming Windows, say otherwise if that's incorrect), the path might be:
"C:/Users/MyUser/Desktop/image.png"


It is often better to specify the resources relatively, for example, I might have a program in the current directory, and then a "resources" folder that contains images, and then the relative path would simply be:
"./resources/image.png"

2. There are various libraries you can download to help you open an image.
I have found stb_image to be easy to use: https://github.com/nothings/stb
You can download a single header file here: https://raw.githubusercontent.com/nothings/stb/master/stb_image.h

Then, use it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>

extern "C" {
    #define STB_IMAGE_IMPLEMENTATION
    #include "stb_image.h"
}

int main()
{
    std::string filename = "image.png";
    
    // ... x = width, y = height, n = # 8-bit components per pixel ...
    // ... replace '0' with '1'..'4' to force that many components per pixel
    // ... but 'n' will always be the number that it would have been if you said 0
    int x,y,n;
    unsigned char *data = stbi_load(filename.c_str(), &x, &y, &n, 0);
    
    // ... process data if not NULL ..
    if (data != nullptr && x > 0 && y > 0)
    {
        if (n == 3)
        {
            
            std::cout << "First pixel: RGB "
                      << static_cast<int>(data[0]) << " "
                      << static_cast<int>(data[1]) << " "
                      << static_cast<int>(data[2]);
        }
        else if (n == 4)
        {
            std::cout << "First pixel: RGBA "
                      << static_cast<int>(data[0]) << " "
                      << static_cast<int>(data[1]) << " "
                      << static_cast<int>(data[2]) << " "
                      << static_cast<int>(data[3]) << '\n';
        }
    }
    else
    {
        std::cout << "Some error\n";
    }

    stbi_image_free(data);
}


Furthermore, you can wrap the stbi code so that C++ handles the memory management for you, by using std::vector.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>

extern "C" {
    #define STB_IMAGE_IMPLEMENTATION
    #include "stb_image.h"
}

// Loads as RGBA... even if file is only RGB
// Feel free to adjust this if you so please, by changing the 4 to a 0.
bool load_image(std::vector<unsigned char>& image, const std::string& filename, int& x, int&y)
{
    int n;
    unsigned char* data = stbi_load(filename.c_str(), &x, &y, &n, 4);
    if (data != nullptr)
    {
        image = std::vector<unsigned char>(data, data + x * y * 4);
    }
    stbi_image_free(data);
    return (data != nullptr);
}

int main()
{
    std::string filename = "image.jpg";
    
    int width, height;
    std::vector<unsigned char> image;
    bool success = load_image(image, filename, width, height);
    if (!success)
    {
        std::cout << "Error loading image\n";
        return 1;
    }
    
    std::cout << "Image width = " << width << '\n';
    std::cout << "Image height = " << height << '\n';
    
    const size_t RGBA = 4;
    
    int x = 3;
    int y = 4;
    size_t index = RGBA * (y * width + x);
    std::cout << "RGBA pixel @ (x=3, y=4): " 
              << static_cast<int>(image[index + 0]) << " "
              << static_cast<int>(image[index + 1]) << " "
              << static_cast<int>(image[index + 2]) << " "
              << static_cast<int>(image[index + 3]) << '\n';

    return 0;
}

Image width = 71
Image height = 76
Pixel @ (x=3, y=4): 77 172 255 255


I had it load as RGBA (PNGs, for example, can have transparency), but feel free to use 3 components instead (RGB). Just change the last argument in stbi_load to 3, and likewise change the the index = logic to use 3 instead of 4.
Last edited on
it's hard to understand everything but thank you.
how can i create png image?
there's header stb_image_write.h so i guess i should use it but don't know how.
Yes, stb_image_write header can help you there.
https://github.com/nothings/stb/blob/master/stb_image_write.h
Read through the comments at the beginning of the file,
There are five functions, one for each image file format:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);

The extra argument for PNG refers to the following:
For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
a row of pixels to the first byte of the next row of pixels.

Here's an example by someone else, with pretty pictures:
http://chanhaeng.blogspot.com/2018/12/how-to-use-stbimagewrite.html

If there's something in particular you don't understand, let us know. It takes some persistence and exploring to understand things, so be prepared for that. Try to just start with small examples, like writing a single red pixel to a file, and then try to work your way up.

The reason I used stbi is because I originally used code from a library called SFML, which also can read/write images.
https://www.sfml-dev.org/documentation/2.5.1/Image_8hpp_source.php
https://github.com/SFML/SFML/blob/master/include/SFML/Graphics/Image.hpp
https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/Image.cpp
https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/ImageLoader.cpp

ImageLoader.cpp is the file that actually uses stbi, which is how I learned to use it.
See the ImageLoader::loadImageFromFile and ImageLoader::saveImageToFile functions.

_______________________________________

There are other libraries people have made, if you don't prefer stbi. For example there's a library called LodePNG that can read/write PNG files.
https://github.com/lvandeve/lodepng
Read through the README on that page for explanation.

+++++++++++++++++++++++++++++++++++

If you're new to C++ or programming in general, I suggest learning just C++/programming before you tackle multimedia stuff like images. But up to you, if you want the challenge. Working with images definitely make some things more fun.
Last edited on
thanks, i know really basics of c++ and made some game prototypes with game maker so just need to understand what does what here.
Topic archived. No new replies allowed.