2016-11-05 2 views
0

Я использую библиотеку libjpeg для чтения и копирования JPEG в программу редактирования, что я пишу в C++Извлечение RGB из изображения JPEG, используя libjepg

У меня есть буфер дисплея, который представляет собой вектор типа данных называется ColorData

Все ColorData состоит из 3 поплавок (RGB)

Вот мой код, который открывает файлы в формате JPEG

PixelBuffer * IOManager::load_jpg_to_pixel_buffer(const char *file_name){ 
    struct jpeg_decompress_struct cinfo; 

    FILE * infile; 

    JSAMPARRAY buffer; 

    if ((infile = fopen(file_name, "rb")) == NULL) { 
    std::cout << "Could not open the jpg file: " << file_name << std::endl; 
    return nullptr; 
    } 

    struct jpeg_error_mgr jerr; 

    cinfo.err = jpeg_std_error(&jerr); 

    jpeg_create_decompress(&cinfo); 

    jpeg_stdio_src(&cinfo, infile); 
    jpeg_read_header(&cinfo, TRUE); 
    jpeg_start_decompress(&cinfo); 

    int width = static_cast<int>(cinfo.output_width); 

    int height = static_cast<int>(cinfo.output_height); 

    std::cout << typeid(cinfo.colormap).name() << std::endl; 

    std::cout << "Width: " << width << "Height: " << height << std::endl; 

    PixelBuffer * image_buffer = new PixelBuffer(width, height, ColorData()); 

    std::cout << cinfo.output_components << std::endl; 

    buffer = (*cinfo.mem->alloc_sarray) 
    ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width * cinfo.output_components, 1); 

    /* Step 6: while (scan lines remain to be read) */ 
    /*   jpeg_read_scanlines(...); */ 

    /* Here we use the library's state variable cinfo.output_scanline as the 
    * loop counter, so that we don't have to keep track ourselves. 
    */ 
    while (cinfo.output_scanline < cinfo.output_height) { 
    /* jpeg_read_scanlines expects an array of pointers to scanlines. 
    * Here the array is only one element long, but you could ask for 
    * more than one scanline at a time if that's more convenient. 
    */ 
    (void) jpeg_read_scanlines(&cinfo, buffer, 1); 
    /* Assume put_scanline_someplace wants a pointer and sample count. */ 

    } 

    return nullptr; 


} 

Как я могу получить значение RGB от т он jpeg использует libjpeg?

+0

файлы JPEG являются [YCbCr закодированное] (https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion), возможно с [выборочной выборкой цветности] (https://en.wikipedia.org/wiki/Chroma_subsampling). Вам придется либо написать необходимый код преобразования цвета, либо использовать библиотеку, которая может сделать это за вас. – Cornstalks

+0

@Cornstalks, libjpeg имеет готовые конверсии, вы просто должны указать правильный 'out_color_space' – Dmitry

+0

@Dmitry: Спасибо за исправление! – Cornstalks

ответ

0

Значения RGB находятся в buffer. На самом деле это массив массивов, поэтому вам нужно индексировать buffer[0].

Что-то вроде этого:

while (cinfo.output_scanline < cinfo.output_height) 
{ 
    (void) jpeg_read_scanlines(&cinfo, buffer, 1); 

    // get the pointer to the row: 
    unsigned char* pixel_row = (unsigned char*)(buffer[0]); 
    // iterate over the pixels: 
    for(int i = 0; i < cinfo.output_width; i++) 
    { 
     // convert the RGB values to a float in the range 0 - 1 
     float red = (float)(*pixel_row++)/255.0f; 
     float green = (float)(*pixel_row++)/255.0f; 
     float blue = (float)(*pixel_row++)/255.0f; 
    } 
} 

Это предполагает, что cinfo.output_components является 3.

Смежные вопросы