Сейчас я работаю над программой для моего курса по обработке визуальной информации.Мы получили скелетные шаблоны для всех домашних заданий, поскольку в центре внимания класса не изучение MFC.Я программирую на Mac и не имею доступа к библиотеке Windows, что упрощает импорт BMP.Поэтому я использовал (и немного изменил) код, найденный на этом сайте: paulbourke.net / dataformats / bmp /
Я фактически использовал этот код в прошлом году,и он отлично работал для 24-битных BMP (то есть с пикселями, представленными как RGB).Основной настройкой, которую мне нужно было сделать, было добавление специальной процедуры, которая инвертирует строки изображения, если высота BMP выражается как отрицательное число.
Когда я импортирую BMP в массивтипа GLubyte, и изображение имеет biBitCount = 24, использование GLDrawPixels прекрасно работает:
http://i.imgur.com/41TVo.png
Однако, когда я импортирую BMP с biBitCount = 8 и отображаю его с помощью GLDrawPixels, я получаюследующее (обратите внимание на ошибку обтекания, выделенную красным прямоугольником):
http://i.imgur.com/xws5j.png
Мне пришлось реализовать алгоритм автоматического определения порога для моего последнего назначения, чтобы облегчить сегментацию изображения наинтерпретируемые регионы.Я думаю, что ошибка для этой обертки связана с импортом BMP, а не с вызова GLDrawPixels.Это связано с тем, что созданный мною алгоритм регионализации определил больше регионов, чем следовало бы.Что, по-видимому, подразумевает, что та часть, которая обернута вокруг, действительно не пересекается в представлении массива BMP.
Я несколько раз просматривал свой код и не могу на всю жизнь понять, что вызываетэта проблема.
Вот код, который отображает BMP после его импорта:
void drawBMP(BITMAPINFO *bitmapInfo, GLubyte *bitmapIn, GLfloat xOffset, GLfloat yOffset) {
if (bitmapInfo) {
glRasterPos2f(xOffset, yOffset);
if (bitmapInfo->bmiHeader.biBitCount == 24) {
glDrawPixels(bitmapInfo->bmiHeader.biWidth,
bitmapInfo->bmiHeader.biHeight,
GL_BGR, GL_UNSIGNED_BYTE, bitmapIn);
} else {
glDrawPixels(bitmapInfo->bmiHeader.biWidth,
bitmapInfo->bmiHeader.biHeight,
GL_LUMINANCE, GL_UNSIGNED_BYTE, bitmapIn);
}
}
glFinish();
}
Возможно, проблема вызвана настройкой GL_LUMINANCE?
Вот функция, которая выполняет фактический импортиз BMP:
GLubyte * /* O - Bitmap data */
LoadDIBitmap(const char *filename, /* I - File to load */
BITMAPINFO **info) /* O - Bitmap information */
{
FILE *fp; /* Open file pointer */
GLubyte *bits; /* Bitmap pixel bits */
GLubyte *ptr; /* Pointer into bitmap */
GLubyte temp; /* Temporary variable to swap red and blue */
int x, y; /* X and Y position in image */
int length; /* Line length */
int bitsize; /* Size of bitmap */
int infosize; /* Size of header information */
BITMAPFILEHEADER header; /* File header */
/* Try opening the file; use "rb" mode to read this *binary* file. */
if ((fp = fopen(filename, "rb")) == NULL)
return (NULL);
/* Read the file header and any following bitmap information... */
header.bfType = read_word(fp);
header.bfSize = read_dword(fp);
header.bfReserved1 = read_word(fp);
header.bfReserved2 = read_word(fp);
header.bfOffBits = read_dword(fp);
if (header.bfType != BF_TYPE) /* Check for BM reversed... */
{
/* Not a bitmap file - return NULL... */
fclose(fp);
return (NULL);
}
infosize = header.bfOffBits - 18;
if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFO))) == NULL)
{
/* Couldn't allocate memory for bitmap info - return NULL... */
fclose(fp);
return (NULL);
}
(*info)->bmiHeader.biSize = read_dword(fp);
(*info)->bmiHeader.biWidth = read_long(fp);
(*info)->bmiHeader.biHeight = read_long(fp);
(*info)->bmiHeader.biPlanes = read_word(fp);
(*info)->bmiHeader.biBitCount = read_word(fp);
(*info)->bmiHeader.biCompression = read_dword(fp);
(*info)->bmiHeader.biSizeImage = read_dword(fp);
(*info)->bmiHeader.biXPelsPerMeter = read_long(fp);
(*info)->bmiHeader.biYPelsPerMeter = read_long(fp);
(*info)->bmiHeader.biClrUsed = read_dword(fp);
(*info)->bmiHeader.biClrImportant = read_dword(fp);
if (infosize > 40)
if (fread((*info)->bmiColors, infosize - 40, 1, fp) < 1)
{
/* Couldn't read the bitmap header - return NULL... */
free(*info);
fclose(fp);
return (NULL);
}
/* Now that we have all the header info read in, allocate memory for *
* the bitmap and read *it* in... */
if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0)
bitsize = ((*info)->bmiHeader.biWidth *
(*info)->bmiHeader.biBitCount+7) / 8 *
abs((*info)->bmiHeader.biHeight);
if ((bits = malloc(bitsize)) == NULL)
{
/* Couldn't allocate memory - return NULL! */
free(*info);
fclose(fp);
return (NULL);
}
if (fread(bits, 1, bitsize, fp) < bitsize)
{
/* Couldn't read bitmap - free memory and return NULL! */
free(*info);
free(bits);
fclose(fp);
return (NULL);
}
//This needs to be done when the height is negative
if ((*info)->bmiHeader.biHeight < 0) {
(*info)->bmiHeader.biHeight *= -1;
int bitsPerPixel = (*info)->bmiHeader.biBitCount;
int bytesPerPixel;
if (bitsPerPixel >= 8) {
bytesPerPixel = bitsPerPixel/8;
} else {
exit(1);
}
int i; //Row
int j; //Column
for (i = 0; i < floor((*info)->bmiHeader.biHeight/2); i++) {
int inlineRowValue = i * (*info)->bmiHeader.biWidth * bytesPerPixel;
int inlineInvRowValue = ((*info)->bmiHeader.biHeight - i) * (*info)->bmiHeader.biWidth * bytesPerPixel;
for (j = 0; j < (*info)->bmiHeader.biWidth; j++) {
int inlineColumnValue = j * bytesPerPixel;
int currentPos = inlineRowValue + inlineColumnValue;
int invCurrentPos = inlineInvRowValue + inlineColumnValue;
int k;
GLubyte *temp = malloc(sizeof(GLubyte)*bytesPerPixel);
for (k = 0; k < bytesPerPixel; k++) {
temp[k] = bits[currentPos+k];
}
for (k = 0; k < bytesPerPixel; k++) {
bits[currentPos+k] = bits[invCurrentPos+k];
bits[invCurrentPos+k] = temp[k];
}
free(temp);
}
}
}
/* OK, everything went fine - return the allocated bitmap... */
fclose(fp);
return (bits);
}
Моя интуиция подсказывает мне, что указатель файла не увеличивается должным образом, поскольку вещи считываются из файла BMP.
Если вы, ребята, знаете, каков источник этой ошибки, пожалуйста, поделитесь.Я буду невероятно благодарен.Это сводит меня с ума.