Сохранение части экрана в файл (SOIL и glReadPixels)

Я пытаюсь сохранить изображение размером 5x5 пикселей, прочитанное с помощью glReadPixels в файл с помощью SOIL.

Я читаю пиксели:

int x = 400;
int y = 300;
std::vector< unsigned char* > rgbdata(4*5*5);
glReadPixels(x, y, 5, 5,GL_RGBA,GL_UNSIGNED_BYTE, &rgbdata[0]); 

Затем я пытаюсь сохранить прочитанные данные с помощью функции сохранения изображения SOIL.

int save_result = SOIL_save_image
    (
    "image_patch.bmp",
    SOIL_SAVE_TYPE_BMP,
    5, 5, 4,
    rgbdata[0]
    );

Но при попытке сохранить изображение я получаю необработанное исключение.

Решение (автор Кристиан Рау)

int x = 400;
int y = 300;
std::vector< unsigned char > rgbdata(4*5*5);
glReadPixels(x-(5/2), y-(5/2), 5, 5,GL_RGBA,GL_UNSIGNED_BYTE, &rgbdata[0]);

int save_result = SOIL_save_image
    (
    "image_patch.bmp",
    SOIL_SAVE_TYPE_BMP,
    5, 5, 4,
    rgbdata.data()
    );

person Købmanden    schedule 20.06.2013    source источник
comment
Вам нужно будет добавить больше деталей...   -  person Mark Ingram    schedule 20.06.2013


Ответы (2)


Вы создаете вектор указателей на unsigned char (std::vector<unsigned char*>, но вам нужен просто вектор на unsigned char (std::vector<unsigned char>).

И при вызове SOIL_save_image вам не нужно давать ему rgbdata[0], который будет одним беззнаковым символом (и с вашим неправильным типом вектора неинициализированный указатель, что, вероятно, приведет к некоторой ошибке доступа к памяти), а указатель на полные данные и, следовательно, rgbdata.data() (или &rgbdata[0], если у вас нет C++11).

person Christian Rau    schedule 20.06.2013
comment
Спасибо. Теперь это работает, однако я получаю только черные пятна изображения. Я опубликую свое решение, когда получу его. - person Købmanden; 20.06.2013
comment
Вы забыли *. В остальном +1. - person Kevin; 20.06.2013
comment
@Kevin Спасибо, ответ стал намного более запутанным. - person Christian Rau; 20.06.2013

Также обратите внимание:

По умолчанию ширина упакованного/распакованного изображения GL должна быть кратна 4, то есть width в glReadPixels(x, y, width, height, format, type, data) должно соответствовать условию width % 4 == 0.

Если width % 4 != 0 (в вашем случае 5 % 4 != 0), это может привести к неожиданным результатам. Таким образом, вы также должны избегать этих проблем, и вот решение:

glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glPixelStorei(GL_PACK_ALIGNMENT,1);
person xtluo    schedule 03.01.2017