我无法加载bmp图像

I am unable to load a .BMP image

本文关键字:bmp 图像 加载      更新时间:2023-10-16

我是opengl新手。我正在尝试使用opengl加载图像。但我不能这样做。它给了我这个错误:

*** Error in `./lena': double free or corruption (top) : 0x0000000001353070 ***

我不知道我做错了什么。我的代码如下所示。实际上这不是我的代码。我在Stack Overflow的另一篇文章中看到过,作者是一个叫Ollo的人。

#include <bits/stdc++.h>
#include <GL/glut.h>
using namespace std;
struct BITMAPFILEHEADER
{
    int bfType;  //specifies the file type
    long long bfSize;  //specifies the size in bytes of the bitmap file
    int bfReserved1;  //reserved; must be 0
    int bfReserved2;  //reserved; must be 0
    long long bOffBits;  //species the offset in bytes from the bitmapfileheader to the bitmap bits
};
struct BITMAPINFOHEADER
{
    long long biSize;  //specifies the number of bytes required by the struct
    long long biWidth;  //specifies width in pixels
    long long biHeight;  //species height in pixels
    int biPlanes; //specifies the number of color planes, must be 1
    int biBitCount; //specifies the number of bit per pixel
    long long biCompression;//spcifies the type of compression
    long long biSizeImage;  //size of image in bytes
    long long biXPelsPerMeter;  //number of pixels per meter in x axis
    long long biYPelsPerMeter;  //number of pixels per meter in y axis
    long long biClrUsed;  //number of colors used by th ebitmap
    long long biClrImportant;  //number of colors that are important
};
int main(void){
    FILE *filePtr;
    BITMAPFILEHEADER bitmapFileHeader;
    BITMAPINFOHEADER *bitmapInfoHeader = new BITMAPINFOHEADER;
    unsigned char *bitmapImage;  //store image data
    int imageIdx=0;  //image index counter
    unsigned char tempRGB;  //our swap variable
    filePtr = fopen("lena.bmp","rb");
    if (filePtr == NULL)
        cout << "ERROR!!! 1" << endl;
    fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);
    fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr); // small edit. forgot to add the closing bracket at sizeof
    //move file point to the begging of bitmap data
    fseek(filePtr, bitmapFileHeader.bOffBits, SEEK_SET);
    //allocate enough memory for the bitmap image data
    bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
    //verify memory allocation
    if (!bitmapImage)
    {
        free(bitmapImage);
        fclose(filePtr);
    }
    //read in the bitmap image data
    fread(bitmapImage, bitmapInfoHeader->biSizeImage, 1, filePtr);
    //make sure bitmap image data was read
    if (bitmapImage == NULL)
    {
        fclose(filePtr);
    }
    //swap the r and b values to get RGB (bitmap is BGR)
    for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
    {
        tempRGB = bitmapImage[imageIdx];
        bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
        bitmapImage[imageIdx + 2] = tempRGB;
    }
    return 0;
}

你从StackOverflow上的另一个答案得到的代码有一些尴尬的问题。

  1. 它检查bitmapImage是否为0,如果是,它立即在bitmapImage
  2. 上调用free (...)
  3. 需要在失败时返回以防止崩溃。
  4. fread (...)不改变bitmapImage是否为NULL

这里有一些你需要做的最小的改变:

if (filePtr == NULL) {
    cout << "ERROR!!! 1" << endl;
    return -1; // FAILURE, so return!
}
[...]
//allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
//verify memory allocation
if (!bitmapImage)
{
    //free(bitmapImage); // This does not belong here!
    fclose(filePtr);
    return -2; // FAILURE, so return!
}
//read in the bitmap image data
fread(bitmapImage, bitmapInfoHeader->biSizeImage, 1, filePtr);
// THIS IS POINTLESS TOO, fread (...) is not going to change the address of
//                          bitmapImage.
/*
//make sure bitmap image data was read
if (bitmapImage == NULL)
{
    fclose(filePtr);
}
*/
//swap the r and b values to get RGB (bitmap is BGR)
for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
{
    tempRGB = bitmapImage[imageIdx];
    bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
    bitmapImage[imageIdx + 2] = tempRGB;
}

正如我在评论中提到的,您不应该编写自己的代码来读取.bmp文件(除非它是用于赋值或类似的东西)。你说你在mint linux上,所以你可能会尝试FreeImage或ImageMagick。例如,您使用的代码不处理索引颜色图像,可能还有许多其他事情。

这就是我如何加载每像素24位的BMP文件,而不是索引颜色位图,从这里下载winbgim: http://www.mediafire.com/file/z9wnl0c70tiacqn/winbgim_DevCpp.zip/file,是在dev-c++中,你可能要为链接器加载几个参数,路径是:项目,项目选项,参数,并写:-lbgi -lgdi32 -luser32 -lcomdlg32 -luuid -loleaut32 -lole32 -mwindows -lwinmm,还有一件事,安装winbgim后,进入dev c,创建一个新项目作为控制台图形应用程序,如果winbgim正确安装,这个项目必须在项目列表中。我写了"写入共享内存",因为我也在内存中写入了文件,尽管我没有以这种方式访问文件,但从同一个文件

 #include <winbgim.h>
 #include <string.h>
 #include<windows.h>
 #include<stdio.h>
 #include <stdlib.h>
 const char *Filename;
 BITMAPFILEHEADER FileHeader;
 BITMAPINFOHEADER InfoHeader;
 int k;
 typedef struct{
 BYTE colorr;
 BYTE colorg;
 BYTE colorb;
 }cine;
 cine color;
 HANDLE hArch, hProy;
 LPSTR base,puntero;
 DWORD tam;
 int main()
 {
 int gdriver=9;
 int gmode=2;
 // initgraph(&gdriver,&gmode, "");
 cleardevice();
 UnmapViewOfFile(base);
 CloseHandle(hProy);
 CloseHandle(hArch);
 char *p;
 char *base;
 DWORD buf;
 Filename="D:\music\IMSLP00795-BWV0971\01.bmp";
 int gd = DETECT, gm;
 int x = 320, y = 240, radius;
 k=0;
 int i;
 int j;


 FILE *File=NULL;
 if(!Filename)
 {
 MessageBox(NULL,"Konnte Filename nicht  finden!","Error",MB_OK|MB_ICONERROR);
 }
 else
 {
 File=fopen("D:\music\IMSLP00795-BWV0971\01.bmp","rb");
 }
 fread(&FileHeader,sizeof(BITMAPFILEHEADER),1,File);
 if(FileHeader.bfType != 0x4D42)
 {
 MessageBox(NULL,"Ungültiges Bildformat!","Error",MB_OK|MB_ICONERROR);
 exit(1); 
 }
 printf("tamaño total del archivo %dn",FileHeader.bfSize);
 printf("comienzo del mapa de bits (imagen en pixels) en bits         %dn",FileHeader.bfOffBits);
 buf=FileHeader.bfOffBits/8; //offset from the begining of BMP file (pixel array)
 printf("comienzo del mapa de bits en bytes desde el origen del archivo      %dn",buf);
 fread(&InfoHeader,sizeof(BITMAPINFOHEADER),1,File);
 printf("horizontal resolution in pixels por metro %lin",InfoHeader.biWidth);
 printf("vertical resolution in pixels por metro %lin",InfoHeader.biHeight);
 printf("numero de bits por pixel %d", InfoHeader.biBitCount);
 initwindow(InfoHeader.biWidth,InfoHeader.biHeight);

 hArch = CreateFile("D:\music\IMSLP00795-BWV0971\01.bmp", /* file  name */
 GENERIC_ALL , /* read/write access */
 0, /* no sharing of the file */
 NULL, /* default security */
 OPEN_ALWAYS, /* open new or existing file */
 FILE_ATTRIBUTE_NORMAL, /* routine file attributes */
 NULL); /* no file template */
 if (hArch==INVALID_HANDLE_VALUE){
 fprintf(stderr,"no puede abrirse el archivo");
 }
 hProy = CreateFileMapping(hArch, /* file handle */
 NULL, /* default security */
 PAGE_READWRITE, /* read/write access to mapped pages */
 0, /* map entire file */
 0,
 TEXT("SharedObject")); /* named shared memory object */
 /* write to shared memory */
 base=(LPSTR)MapViewOfFile(hProy,FILE_MAP_ALL_ACCESS,0,0,0);
 tam=GetFileSize(hArch,NULL);
 int cont=0;
 puntero=base;
 p=base+FileHeader.bfOffBits;
 k=0;int t=0,v,l;
 fseek(File,FileHeader.bfOffBits,SEEK_SET );
 int read=0,read2=0;
 k=0;
 for( i=0; i<InfoHeader.biWidth; i++ ) {
       fread(&color,sizeof(cine),1,File);
        read += sizeof(cine);
        printf( "Pixel %d: %3d %3d %3dn", i+1, int(color.colorb),         int(color.colorg), int(color.colorr) );
    }
    if( read % 4 != 0 ) {
        read2 = 4 - (read%4);
        printf( "Padding: %d bytesn", read2 );
        //fread( &color, read2, 1, File );
    }
    fseek(File,FileHeader.bfOffBits,SEEK_SET );
    for (i=0;i<InfoHeader.biHeight;i++)
 for(j=0;j<InfoHeader.biWidth ;j++)
{
 fread(&color,sizeof(cine),1,File);
 putpixel(j,InfoHeader.biHeight-  i,COLOR(int(color.colorb),int(color.colorg),int(color.colorr)));
 if(j==InfoHeader.biWidth-1&&read2!=0)fseek(File,read2,SEEK_CUR);
} 
 fclose(File);
 UnmapViewOfFile(base);
 CloseHandle(hProy);
 CloseHandle(hArch);
 getch();
}