How do I read JPEG and PNG pixels in C++ on Linux?

后端 未结 9 2383
北荒
北荒 2020-12-04 18:34

I\'m doing some image processing, and I\'d like to individually read each pixel value in a JPEG and PNG images.

In my deployment scenario, it would be awkward for me

9条回答
  •  孤街浪徒
    2020-12-04 18:54

    As Nils pointed, there is no such thing as a C or C++ standard library for JPEG compression and image manipulation.

    In case you'd be able to use a third party library, you may want to try GDAL which supports JPEG, PNG and tens of other formats, compressions and mediums.

    Here is simple example that presents how to read pixel data from JPEG file using GDAL C++ API:

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
        GDALAllRegister(); // once per application
    
        // Assume 3-band image with 8-bit per pixel per channel (24-bit depth)
        std::string const file("/home/mloskot/test.jpg");
    
        // Open file with image data
        GDALDataset* ds = static_cast(GDALOpen(file.c_str(), GA_ReadOnly));
        assert(0 != ds);
    
        // Example 1 - Read multiple bands at once, assume 8-bit depth per band
        {
            int const ncols = ds->GetRasterXSize();
            int const nrows = ds->GetRasterYSize();
            int const nbands = ds->GetRasterCount();
            int const nbpp = GDALGetDataTypeSize(GDT_Byte) / 8;
            std::vector data(ncols * nrows * nbands * nbpp);
    
            CPLErr err = ds->RasterIO(GF_Read, 0, 0, ncols, nrows, &data[0], ncols, nrows, GDT_Byte, nbands, 0, 0, 0, 0);
            assert(CE_None == err);
    
            // ... use data
        }
    
        // Example 2 - Read first scanline by scanline of 1 band only, assume 8-bit depth per band
        {
            GDALRasterBand* band1 = ds->GetRasterBand(1);
            assert(0 != band1);
    
            int const ncols = band1->GetXSize();
            int const nrows = band1->GetYSize();
            int const nbpp = GDALGetDataTypeSize(GDT_Byte) / 8;
            std::vector scanline(ncols * nbpp);
    
            for (int i = 0; i < nrows; ++i)
            {
                CPLErr err = band1->RasterIO(GF_Read, 0, 0, ncols, 1, &scanline[0], ncols, 1, GDT_Byte, 0, 0);
                assert(CE_None == err);
    
                // ... use scanline
            }
        }
    
        return 0;
    }
    

    There is more complete GDAL API tutorial available.

提交回复
热议问题