为什么C ++代码无法显示位图?(来自教科书的代码)

时间:2019-08-28 09:25:49

标签: c++ winapi

我正在尝试在教科书中完成一个示例。尽管我确定我键入了正确的代码,但是只有一个黑色背景的窗口,没有位图“ C.bmp”正在加载。

因为我不精通C ++和winAPI,我只是试图使全部代码正确无警告。我上网冲浪寻找有意义的答案,但没有像我这样的代码。我很困惑。 / p>

我尝试了绝对路径,但仍然无法正常工作。 图像返回(HBITMAP)0x0,而GetLastError返回零。 const char *文件名,但程序仍然会发生 MinGW,gcc 4.9.2编译器

void DrawBitmap(const char *filename,int x,int y)
{
    //load the bitmap image
    HBITMAP image = (HBITMAP)LoadImage(0,filename,IMAGE_BITMAP,
    0,0,LR_LOADFROMFILE);
    GetLastError();
    //read the bitmap's properties
    BITMAP bm;
    GetObject(image,sizeof(BITMAP),&bm);
    //create a device context for the bitmap
    HDC hdcImage = CreateCompatibleDC(device);
    SelectObject(hdcImage,image);
    //draw the bitmap to the window (bit block transfer)
    BitBlt(
        device,                 //destination device context    
        x,y,                    //x,y location on destination
        bm.bmWidth,bm.bmHeight, //width,height of source bitmap
        hdcImage,               //source bitmap device context
        0,0,                    //start x,y on source bitmap
        SRCCOPY);               //blit method
    //delete the device context and bitmap
    DeleteDC(hdcImage);
    DeleteObject((HBITMAP)image);
}
void Game_Run()
{
    if(gameover == true) return;
    //get the drawing surface
    RECT rect;
    GetClientRect(window,&rect);
    //draw bitmap at random location
    int x = rand() % (rect.right -rect.left);
    int y = rand() % (rect.bottom -rect.top);
    const char* filename = "E:\\Study\\time\\Code\\C++\\gameloop\\bmp.bmp";
    DrawBitmap(filename,x,y);
}

我只想加载位图并知道为什么。

3 个答案:

答案 0 :(得分:3)

运行代码,首先将代码逻辑放在一边,只是为了显示BMP图像,您未添加正确的图像路径。

您可以尝试添加图片的绝对路径。

赞:

int x;
cin >> x;
char arr [x];

已更新:

我用GCC 4.9.2编译器MinGW重新测试了代码。它可以正确显示图像。看我所附的GIF图片。

1

从稍后的反馈结果来看,void foo(int size) { char arr [size]; // do something } void main() { foo(10); foo(20); } 返回NULL,您可以使用DrawBitmap("C:\\Users\\strives\\source\\C.bmp",x,y); //This is my picture path. Please enter your picture path correctly. 测试返回值0。理论上,如果图像加载失败,它将返回2。您可以使用Loadimage重新测试返回值。同时,您需要确保所添加的BMP图像正确,已打开并且为BMP格式。图片

答案 1 :(得分:2)

不显示位图的原因很可能是因为位图文件放置在错误的位置。在Release中构建此代码,在项目目录中查找,找到实际的Release可执行文件,将“ C.bmp”复制到可执行文件所在的目录中,并双击运行该可执行文件。您会看到它有效。

您不会说出您使用的是哪个IDE,但是,假设您具有某种Visual Studio的风格,则可以通过从IDE启动来使其正常工作,除非您更改了设置,默认情况下,Visual Studio使用“工作目录”进行调试是项目目录。如果查看代码在文件系统中的位置,请找到解决方案文件的位置-.sln文件。您应该看到一个目录,该目录是解决方案文件的同级文件,该目录名为您命名的项目。在顶层放置“ C.bmp”,然后尝试从Visual Studio启动。

除了这个问题之外,这段代码还有很多问题。为了让您开始使用,每当您要绘制位图时,都要从文件系统中重新加载位图。

答案 2 :(得分:-1)

仅致电LoadImage是不够的。它被涂成黑色,因为每种颜色都是黑色。另外,您需要重新绘制窗口。您应该加载调色板,其内容可能取决于您的上下文。 https://support.microsoft.com/en-gb/help/158898/howto-how-to-use-loadimage-to-read-a-bmp-file

中的示例
BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,
   HPALETTE *phPalette )
   {

   BITMAP  bm;

   *phBitmap = NULL;
   *phPalette = NULL;

   // Use LoadImage() to get the image loaded into a DIBSection
   *phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0,
               LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
   if( *phBitmap == NULL )
     return FALSE;

   // Get the color depth of the DIBSection
   GetObject(*phBitmap, sizeof(BITMAP), &bm );
   // If the DIBSection is 256 color or less, it has a color table
   if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
   {
   HDC           hMemDC;
   HBITMAP       hOldBitmap;
   RGBQUAD       rgb[256];
   LPLOGPALETTE  pLogPal;
   WORD          i;

   // Create a memory DC and select the DIBSection into it
   hMemDC = CreateCompatibleDC( NULL );
   hOldBitmap = (HBITMAP)SelectObject( hMemDC, *phBitmap );
   // Get the DIBSection's color table
   GetDIBColorTable( hMemDC, 0, 256, rgb );
   // Create a palette from the color tabl
   pLogPal = (LOGPALETTE *)malloc( sizeof(LOGPALETTE) + (256*sizeof(PALETTEENTRY)) );
   pLogPal->palVersion = 0x300;
   pLogPal->palNumEntries = 256;
   for(i=0;i<256;i++)
   {
     pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed;
     pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen;
     pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue;
     pLogPal->palPalEntry[i].peFlags = 0;
   }
   *phPalette = CreatePalette( pLogPal );
   // Clean up
   free( pLogPal );
   SelectObject( hMemDC, hOldBitmap );
   DeleteDC( hMemDC );
   }
   else   // It has no color table, so use a halftone palette
   {
   HDC    hRefDC;

   hRefDC = GetDC( NULL );
   *phPalette = CreateHalftonePalette( hRefDC );
   ReleaseDC( NULL, hRefDC );
   }
   return TRUE;

   }

接下来,您必须将其平移到窗口:

case WM_PAINT:
   {
     PAINTSTRUCT   ps;
     HBITMAP       hBitmap, hOldBitmap;
     HPALETTE      hPalette, hOldPalette;
     HDC           hDC, hMemDC;
     BITMAP        bm;

   hDC = BeginPaint( hWnd, &ps );

   if( LoadBitmapFromBMPFile( szFileName, &hBitmap, &hPalette ) )
   {
      GetObject( hBitmap, sizeof(BITMAP), &bm );
      hMemDC = CreateCompatibleDC( hDC );
      hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
      hOldPalette = SelectPalette( hDC, hPalette, FALSE );
      RealizePalette( hDC );

      BitBlt( hDC, 0, 0, bm.bmWidth, bm.bmHeight,
              hMemDC, 0, 0, SRCCOPY );

      SelectObject( hMemDC, hOldBitmap );
      DeleteObject( hBitmap );
      SelectPalette( hDC, hOldPalette, FALSE );
      DeleteObject( hPalette );
   }
   EndPaint( hWnd, &amp;ps );

   }
   break;

该示例很笨拙,因为每次绘制窗口时都会加载图像。您必须要重新组织代码,以便映像仅被加载一次。但这是您应该做的-在窗口事件处理程序中对其进行绘制,因为每次移动,调整大小或以其他方式使窗口无效(模糊)时,都需要重新绘制。