我正在尝试使用developer's image library (DevIL)将原始灰度图像保存到磁盘上的png图像中。
根据this post。看起来所有魔鬼都需要提供一个带有一些图像元数据和图像大小的标头。但是,当我尝试将图像加载到其堆栈中时,它给了我一个IL_INVALID_PARAM错误。
#include <iostream>
#include <vector>
#include <assert.h>
// Include Devil
#include <IL/il.h>
#include <IL/ilu.h>
#define IMAGE_HEIGHT 16
#define IMAGE_WIDTH 16
#define IMAGE_DEPTH 1
#define BYTES_PER_PIXEL 1
#define NUM_PIXELS IMAGE_WIDTH*IMAGE_HEIGHT
#define HEADER_SIZE 13
// from: https://stackoverflow.com/questions/27609152/how-to-load-devil-image-from-raw-data
struct RawHeader {
ILuint width; // 32 bit unsigned integer
ILuint height; // 32 bit unsigned integer
ILuint depth; // 32 bit unsigned integer
ILubyte bpp; // 8 bit unsigned {Bytes per pixel}
};
int main() {
printf("running main\n");
// initialize the loading and saving sub library
ilInit();
iluInit();
// create and bind the image id (typically referred to as 'image name' in the docs)
ILuint img_id;
ilGenImages(1, &img_id);
ilBindImage(img_id);
// generate the image and header
RawHeader header = RawHeader();
header.width = IMAGE_WIDTH;
header.height = IMAGE_HEIGHT;
header.depth = IMAGE_DEPTH;
header.bpp = BYTES_PER_PIXEL;
// create the raw image data
auto *raw = (uint8_t *)malloc(NUM_PIXELS + HEADER_SIZE);
//copy the header into the load function is looking for: https://github.com/DentonW/DevIL/blob/master/DevIL/src-IL/src/il_raw.cpp#L71
std::copy((uint8_t *)&header, (uint8_t *)&header + HEADER_SIZE, raw);
// fill raw with a gradient test image
uint8_t *pix_ptr = raw + HEADER_SIZE;
ILubyte pix = 0;
for(int i=0; i < NUM_PIXELS; i++){
*pix_ptr = pix;
pix_ptr++;
pix++;
if(pix >= IMAGE_WIDTH){
pix = 0;
}
}
/*
* We should now be in the format DevIL expects?
* that is a 13 byte header followed by the raw image data
* https://stackoverflow.com/questions/27609152/how-to-load-devil-image-from-raw-data
* https://github.com/DentonW/DevIL/blob/master/DevIL/src-IL/src/il_raw.cpp#L71
*
* According to the docs, IL_INVALID_PARAM should only be raised if lump == NULL
* http://www-f9.ijs.si/~matevz/docs/DevIL/il/f00152.htm
*/
// assure there are no errors before we run our test...
ILenum err = ilGetError();
printf("ERROR CODE BEFORE LOADING: %d - %s\n\n", err, iluErrorString(err) );
// according to docs, we shouldn't be raising a IL_INVALID_PARAM error if this passes?
assert(raw != nullptr);
// Load the image into the Devil Stack
if(!ilLoadL(IL_RAW, raw, NUM_PIXELS) ){
//Print out the header if it fails
auto *raw_header_ptr = (RawHeader *)raw;
printf("HEIGHT: %u, WIDTH: %u, DEPTH: %u, BPP: %hhu\n",
raw_header_ptr->height,
raw_header_ptr->width,
raw_header_ptr->depth,
raw_header_ptr->bpp);
// print out every pixel to make sure the gradient was loaded in correctly
// should be "0 1 2 3 4 ..." for every row
uint8_t *pix_idx = raw + HEADER_SIZE;
for(int i=0; i < IMAGE_HEIGHT; i++ ){
for(int j=0; j < IMAGE_WIDTH; j++){
printf("%hhu ", *pix_idx);
pix_idx++;
}
printf("\n");
}
err = ilGetError();
printf("\nERROR CODE AFTER LOADING: %d - %s\n", err, iluErrorString(err) );
printf("failed\n");
return 1;
}
// save the image to disk
ilSaveImage("~/test.png");
ilDeleteImages(1, &img_id);
return 0;
}
我最终得到以下内容
running main
ERROR CODE BEFORE LOADING: 0 - no error
HEIGHT: 16, WIDTH: 16, DEPTH: 1, BPP: 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
ERROR CODE AFTER LOADING: 1289 - invalid parameter
failed
Process finished with exit code 1