Archived

This topic is now archived and is closed to further replies.

HBITMAP grrrrrrrrrr... HELP!

This topic is 5044 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can someone write code how to load a 24-bit bitmap e.g. Test.BMP(using CreatDIBitmap() ) and obtain a pointer to the data in the bitmap ? (i.e. exclude header) I know this is like 100 lines of code, but i am sure many people have it in their head, i am really having trouble. And would very much appreciate someones help. Thanks guys, kalash

Share this post


Link to post
Share on other sites
<< I know this is like 100 lines of code >>

You don't have to parse the BMP. In Win32, you can declare these

HBITMAP hbmp1;
BITMAP bmp1;

Then use this

hbmp1 = (HBITMAP)LoadImage(game_instance, MAKEINTRESOURCE(BMP_NAME1), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
GetObject(hbmp1, sizeof(bmp1), &bmp1);

That's 2 lines. Your BMP is now loaded and ready to be blitted. I am using resources instead of files, but files is similar. GDI example:

Megaman.cpp | EXE

The DirectDraw version, you declare this

LPDIRECTDRAWSURFACE hbmp1 = NULL;

Then use this

hbmp1 = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_NAME1), 0, 0);

That's 1 line. The DDLoadBitmap uses LoadImage and is part of ddutil.cpp | .h which you include. DirectDraw example:

Megaman2.cpp | EXE

I'm into figuring out the simplest way to do this stuff....no parsing of BMP required.

VazGames.com

Phil P

[edited by - PhilVaz on February 19, 2004 8:49:18 PM]

Share this post


Link to post
Share on other sites
I believe the above code will only work if your bitmap is already a resource compiled into your executable... if that's what you want then it's great... however if you want your program to open the file at runtime you have to supply different info to the LoadImage function

find more info here

[edited by - tempuself on February 19, 2004 9:12:00 PM]

Share this post


Link to post
Share on other sites
I dont want to blit it, sorry u misunderstood me... i want to access the RGB bits in the bitmap and pixel values.

here is some code i was just putting together from the "tetris" class on the post above, where am i going wrong?

so bitmapobject.cpp and the header bitmapobject.h are exactly like the guy wrote the with slight modification of mine



//BitMapObject.cpp
#include "bitmapobject.h"

BitMapObject::BitMapObject()
{
hdcMemory=NULL;
hbmNewBitMap=NULL;
hbmOldBitMap=NULL;
iWidth=0;
iHeight=0;
pBuffer = 0;

}

BitMapObject::~BitMapObject()
{
//if the hdcMemory hasn''t been destroyed do so
if(hdcMemory)
Destroy();
}

void BitMapObject:: Load(HDC hdcCompatible, LPCSTR lpszFilename)
{
//if hdcMemory isnt null make it so
if(hdcMemory)
Destroy();

//create memory dc
hdcMemory=CreateCompatibleDC(hdcCompatible);

//load bitmap
hbmNewBitMap=(HBITMAP) LoadImage(NULL, lpszFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

//shove image into the dc
hbmOldBitMap = (HBITMAP) SelectObject(hdcMemory, hbmNewBitMap);

//grab bitmaps properties
BITMAP bmp;

pBuffer= new char[GetObject(hbmNewBitMap,sizeof(BITMAP),(LPVOID)&bmp)];


//GetBitmapBits(hbmNewBitMap,sizeof(BITMAP) ,(LPVOID)&bmp); //bmp.
//GetBitmapBits(hbmNewBitMap,

//grab width and height
iWidth=bmp.bmWidth;
iHeight=bmp.bmHeight;
}


char BitMapObject::GetBitsBuffer()
{
return *pBuffer;
}

void BitMapObject::Create(HDC hdcCompatible, int width, int height)
{
if(hdcMemory)
Destroy();

//create dc memory now that u have destroyed it
hdcMemory=CreateCompatibleDC(hdcCompatible);

//create bitmap
hbmNewBitMap=CreateCompatibleBitmap(hdcCompatible,width,height);

//shove the image into the dc
hbmOldBitMap=(HBITMAP)SelectObject(hdcMemory, hbmNewBitMap);

//change the width and height
iWidth=width;
iHeight=height;

}


void BitMapObject::Destroy()
{
//restore old bitmap
SelectObject(hdcMemory,hbmOldBitMap);

//delete new bitmap
DeleteObject(hbmNewBitMap);

//delete device context
DeleteDC(hdcMemory);

//set members to 0/NULL
hdcMemory=NULL;
hbmNewBitMap=NULL;
hbmOldBitMap=NULL;
iWidth=0;
iHeight=0;
}

BitMapObject::operator HDC ()
{
//return hdcMemory
return(hdcMemory);
}

int BitMapObject::GetWidth()
{
return(iWidth);
}

int BitMapObject::GetHeight()
{
return(iHeight);
}


//here is the header and the my main...

//BitMapObject.h
#ifndef BITMAPOBJECT_H
#define BITMAPOBJECT_H
#pragma once

//windows stuff
#include <windows.h>



class BitMapObject
{
private:
//memory dc
HDC hdcMemory;

//new bitmap
HBITMAP hbmNewBitMap;

//old bitmap
HBITMAP hbmOldBitMap;

//width & height as integers
int iWidth;
int iHeight;

char *pBuffer;

public:

BitMapObject();
~BitMapObject();

//loads bitmap from file
void Load(HDC hdcCompatible, LPCTSTR lpszFilename);

//creates a blank bitmap
void Create(HDC hdcCompatible, int width, int height);

//destroys bitmap and dc
void Destroy();

//return width
int GetWidth();

//return height
int GetHeight();

//get pBuffer
char GetBitsBuffer();

//converts to HDC
operator HDC();

};
#endif



//here is my main....

int main()
{
HDC hdc=GetDC(0);//no window handle so 0.

//

bitmap.Create(hdc,120,120);
bitmap.Load(NULL,"C:\StillCap0000.BMP");


BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)bitmap.GetBitsBuffer();


// Find the address of the start of the image data.
char pD = bitmap.GetBitsBuffer() + sizeof(BITMAPINFOHEADER);

void *pData= &pD;

BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER));
HBITMAP hBitmap = CreateDIBitmap(hdc, bmih, CBM_INIT,
pData, &bmi, DIB_RGB_COLORS);



COLORREF pixels = RGB(0,0,0);
//int frame[][];
int red=0;
int green=0;
int blue=0;

for (int y=0; y {
for (int x=0; x {
pixels=GetPixel(hdc,x,y);
//not finished but problem is not here
red=pixels.bRed;

cout << "\nOkey here we go\n\n"<< bitmap.GetHeight()*bitmap.GetWidth();



}
}



PLEASE Help, i am getting a run-time error....

Share this post


Link to post
Share on other sites
TempusElf, yeah thats exactly what i am trying to do, load a bitmap at runtime... well that bitmap will be overwritten 40 times a second in my application and i want to keep on reloading it as it will be changing and extracting pixels from it... so i need to isolate the header and increment the pointer to correct starting address in order to start getting the pixels.

Need your guys help as C++ and Ms SDK are very new to me but am under "deadline".

Share this post


Link to post
Share on other sites
quote:
Original post by kalash
If someone can tell me the formatting code tags i will re-post the code if u have trouble seeing it this way.

Cheers


[source ] code goes here without spaces in tags [/source ]


Share this post


Link to post
Share on other sites
Thanks mate,

So cpp bitmapobject.cpp



//BitMapObjec.cpp

#include "bitmapobject.h"

BitMapObject::BitMapObject()
{
hdcMemory=NULL;
hbmNewBitMap=NULL;
hbmOldBitMap=NULL;
iWidth=0;
iHeight=0;
pBuffer = 0;

}

BitMapObject::~BitMapObject()
{
//if the hdcMemory hasn''t been destroyed do so

if(hdcMemory)
Destroy();
}

void BitMapObject:: Load(HDC hdcCompatible, LPCSTR lpszFilename)
{
//if hdcMemory isnt null make it so

if(hdcMemory)
Destroy();

//create memory dc

hdcMemory=CreateCompatibleDC(hdcCompatible);

//load bitmap

hbmNewBitMap=(HBITMAP) LoadImage(NULL, lpszFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

//shove image into the dc

hbmOldBitMap = (HBITMAP) SelectObject(hdcMemory, hbmNewBitMap);

//grab bitmaps properties

BITMAP bmp;

pBuffer= new char[GetObject(hbmNewBitMap,sizeof(BITMAP),(LPVOID)&bmp)];


//GetBitmapBits(hbmNewBitMap,sizeof(BITMAP) ,(LPVOID)&bmp); //bmp.

//GetBitmapBits(hbmNewBitMap,


//grab width and height

iWidth=bmp.bmWidth;
iHeight=bmp.bmHeight;
}


char BitMapObject::GetBitsBuffer()
{
return *pBuffer;
}

void BitMapObject::Create(HDC hdcCompatible, int width, int height)
{
if(hdcMemory)
Destroy();

//create dc memory now that u have destroyed it

hdcMemory=CreateCompatibleDC(hdcCompatible);

//create bitmap

hbmNewBitMap=CreateCompatibleBitmap(hdcCompatible,width,height);

//shove the image into the dc

hbmOldBitMap=(HBITMAP)SelectObject(hdcMemory, hbmNewBitMap);

//change the width and height

iWidth=width;
iHeight=height;

}


void BitMapObject::Destroy()
{
//restore old bitmap

SelectObject(hdcMemory,hbmOldBitMap);

//delete new bitmap

DeleteObject(hbmNewBitMap);

//delete device context

DeleteDC(hdcMemory);

//set members to 0/NULL

hdcMemory=NULL;
hbmNewBitMap=NULL;
hbmOldBitMap=NULL;
iWidth=0;
iHeight=0;
}

BitMapObject::operator HDC ()
{
//return hdcMemory

return(hdcMemory);
}

int BitMapObject::GetWidth()
{
return(iWidth);
}

int BitMapObject::GetHeight()
{
return(iHeight);
}



and the header, the bitmapobject.h



//BitMapObject.h

#ifndef BITMAPOBJECT_H
#define BITMAPOBJECT_H
#pragma once

//windows stuff

#include <windows.h>



class BitMapObject
{
private:
//memory dc

HDC hdcMemory;

//new bitmap

HBITMAP hbmNewBitMap;

//old bitmap

HBITMAP hbmOldBitMap;

//width & height as integers

int iWidth;
int iHeight;

char *pBuffer;

public:

BitMapObject();
~BitMapObject();

//loads bitmap from file

void Load(HDC hdcCompatible, LPCTSTR lpszFilename);

//creates a blank bitmap

void Create(HDC hdcCompatible, int width, int height);

//destroys bitmap and dc

void Destroy();

//return width

int GetWidth();

//return height

int GetHeight();

//get pBuffer

char GetBitsBuffer();

//converts to HDC

operator HDC();

};
#endif


















#include <iostream>

#include <qedit.h>

#define WIN32_LEAN_AND_MEAN

#include "bitmapobject.h";

#include <windows.h>

using std::cout;
using std::endl;





BitMapObject bitmap;


int main()
{
HDC hdc=GetDC(0);//no window handle so 0.


//


bitmap.Create(hdc,120,120);
bitmap.Load(NULL,"C:\StillCap0000.BMP");

//char *pBuf = bitmap.GetBitsBuffer()


BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)bitmap.GetBitsBuffer();


// Find the address of the start of the image data.

char pD = bitmap.GetBitsBuffer() + sizeof(BITMAPINFOHEADER);

// Note: In general a BITMAPINFOHEADER can include extra color

// information at the end, so calculating the offset to the image

// data is not generally correct. However, the IMediaDet interface

// always returns an RGB-24 image with no extra color information.

void *pData= &pD;

BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER));
HBITMAP hBitmap = CreateDIBitmap(hdc, bmih, CBM_INIT,
pData, &bmi, DIB_RGB_COLORS);



COLORREF pixels = RGB(0,0,0);
//int frame[][];

int red=0;
int green=0;
int blue=0;

for (int y=0; y<bitmap.GetHeight(); y++)
{
for (int x=0; x<bitmap.GetWidth(); x++)
{
pixels=GetPixel(hdc,x,y);

//red=pixels.bRed;


cout << "\nOkey here we go\n\n"<< bitmap.GetHeight()*bitmap.GetWidth();// pixels.bRed;



// frame[y][x] =


}
}
return (1);





Share this post


Link to post
Share on other sites
<< TempusElf, yeah thats exactly what i am trying to do, load a bitmap at runtime >>

Replace MAKEINTRESOURCE with the file name, and use LR_LOADFROMFILE.

If you''re trying to make Tetris, why bang your head against the wall trying to parse a BMP. Save your bitmap blocks as separate 24-bit bitmaps, and what I gave you will work fine. You will learn more about the BMP format your way at least.

MSDN LoadImage

Phil P

Share this post


Link to post
Share on other sites
hehehehe, no i am not trying to make tetris, i want at run-time to read a bitmap and process it''s pixels (i.e. apply so image processing algorithms) and then later have it again in the game...

I just want somebody to help me get a pointer to the first byte of pixels data.

Share this post


Link to post
Share on other sites
PhilVaz,

i am using LR_LOADFROMFILE :-p
Did u load my program in a project and tried to execute it ?
can u help just print out a few pixel values (0-255,rgb).

Share this post


Link to post
Share on other sites
kalash,

If you like I can extend it so that it puts all the pixel data in a char array and you have PutPixel(x, y, colour) and GetPixel (x, y, colour) functions - is that what you need?

If so let me know ASAP and I''ll sort it.

I.

www.coldcity.com
code, pics, life

Share this post


Link to post
Share on other sites
I just came back, had a few beers here in Manchester, checked my email and wow... i am looking at it now, my night is just about to begin... oh these 3rd year projects

I write you back by email mate, thanks so much.

take care

Share this post


Link to post
Share on other sites
i can send you a tool ("Raw2Code"), which converts arbitrary RAW-files (e.g. from PaintShop) to CPP-unsigned char arrays, if you are interested.

DJSnow
---
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites