Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

bitmap reading - VC++

Posted on 1998-12-27
12
Medium Priority
?
1,097 Views
Last Modified: 2008-02-01
Howto read bitmap and transform it into tiles collection?
0
Comment
Question by:tamnof
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 2

Expert Comment

by:gurpreets
ID: 1181122
I know only the first part.
Actually in VC++ u can't directly load bitmap using MFC support classes .
U have to read the file using header info.
and create a virtual window and using putpixel /putpixelv methods u can write pixel on the virtual window finallly when u call InvalidateRect the paint method will be callled and in paint method  u have to map the the virtual window on the actual physical window.
before reading the file u shold have the knowledge of header of the bitmap.
bitmap is consisting of 50 bytes header and rest all is bitmap data.
in different color format the data is having different formats
16 color --- > 4 bits per pixel
256 color --- >8 bits per pixel
16 K color --- > 65536 bits per pixel
16 M color --- > 3 bytes per pixel
using the header info u can read the data from file u can allocate memory to the pointers
the header is look like this
struct bitmap_header {
BYTE tag[2] ;  //"B" "M"
DWORD zero  ; // "having zer;
DWORD width ; //
DWORD height ; //
WORD bytes_per_pixel ; //

};

 
0
 
LVL 6

Expert Comment

by:thresher_shark
ID: 1181123
You mean a pixel in "16K color," which I have presonally never heard of, contains 8192 bytes per pixel?  Do I see a tpyo?    :-)
0
 

Author Comment

by:tamnof
ID: 1181124
The answer gives to many asumes... It does not gives me a solution or a start for a solution (like how to read BITMAPINFO structure using CArchive & CFile). Also, the comment placed by thresher_shark, concerns with gurpreets's answer, points to a some-how doubt about the conection between my question and gurpreets's answer.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:tamnof
ID: 1181125
I'd don't necessarily, need to show the bitmap, what I realy need is to read the bitmap's information and then to divide it into tiles which will form a new file which will consist of collection of tiles.
                           Thanks
0
 
LVL 1

Expert Comment

by:wirus
ID: 1181126
I think the most convenient would be:
1. You can use ::LoadBitmap() (it will return a handle to bitmap or NULL) to load your sorce bitmap
2. Then use ::CreateDibSection() to create the destination (if you have no limitations to the destination bitmap format, the best would be 24bpp or 8bpp)
3. Create two memory DCs with ::CreateDC() or CDC::CreateCompatibleDC()
4. insert destination and source into their DCs
5. use ::BitBlt() or CDC::BitBlt() to paint your destination
6. since you've used ::CreateDibSection() for creating destination you have a pointer to the bitmap's data, so you can store the destination file you wrote about
7. restore original bitmaps to DCs and free everything
Is that what you wanted to do?
0
 
LVL 1

Expert Comment

by:wirus
ID: 1181127
Something I've forgotten about
instead of ::LoadBitmap() use ::LoadImage() to load it from the disk file
0
 

Author Comment

by:tamnof
ID: 1181128
wirus' answer was good but did not cover an important part of my question which is "...not necessarily, need to show the bitmap, what I realy need is to read the bitmap's information and then to divide it into tiles which will form a new file which will consist of collection of tiles. "
             I think wirus's realy knows what he is talking about - I already have done this part. I'll live the un-handled part for next attempts to answer.
                         Thanks tamnof
0
 
LVL 1

Expert Comment

by:wirus
ID: 1181129
Can you strictly define: how "file consisting of collection of tiles" should look like?

I thought you had bitmap like this:

XAYSAAS
HHSJAGD

and wanted it to look like this:

X|A|Y|S|A|A|S
-------------------
A|A|S|K|D|J|J

where '|' and '-' are any graphic images separating your tiles (can be black, of course)

0
 
LVL 1

Expert Comment

by:wirus
ID: 1181130
One more...
Using DC doesn't mean you have to show the bitmap,
so- look above ("Can you...") :)
0
 

Author Comment

by:tamnof
ID: 1181131
Hi wirus
The tile-collection-file in need to create is a file with a common header, specifying the common attributes of all the tiles (since they all have te same dimention) and after the header, the tiles, controled by CTile class objects (user defined class), will bw serialized in a well controled order into the new created file.
An important part of the header shoud be a table which will give the offset BYTE, from the begining of the file, where each tile starts.
                    Thnks
0
 
LVL 1

Accepted Solution

by:
wirus earned 300 total points
ID: 1181132
So, you have two ways to do it (well, actually three):

1) You can use ::LoadImage() to load your bitmap

CBitmap yourbitmap;
yourbitmap.Attach(::LoadImage(theApp.m_hInstance, "C:\\YOURBITMAP.BMP", IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR|LR_CREATEDIBSECTION|LR_LOADFROMFILE));

giving LR_LOADFROMFILE flag let you get a pointer to the bitmap image bits with:
BITMAP bmp;
yourbitmap.GetBitmap(&bmp);
the pointer is bmp.bmBits ...

use other bmp's members (width, height, bits per pixel and WidthBytes) to manipulate the image (I won't describe you how to do that, I think you know how to allocate memory for your tiles and copy parts of "yourbitmap" using that pointer- you may need to convert it to another bpp format, of course)

2) You can use eg. CFile file to open the bitmap file and its Read() member function to read parts of it:
(Look at help for the description of these structures)
a) read BITMAPFILEHEADER
b) read BITMAPINFOHEADER
c) use BITMAPINFOHEADER fields to determine number of RGBQUAD (palette) entries following it- allocate memory and read them (there will be no palette entries for true color bitmaps) (find in help BITMAPINFO and read the description)
d) use BITMAPFILEHEADER's bfOffBits to determine where image block begins
c) calculate the scan line length in bytes- it must be dividable by 4 and allocate memory for the image (you may also allocate memory for your tiles and read the image there)

3) You can do it as at pt. 1), but for tile memory buffers use bitmaps (but I don't think it's any better...)

-------------------------
I guess you will organize your tiles as an array of CTile objects.
If you derive the CTile class from CObject and use DECLARE_SERIAL and IMPLEMENT_SERIAL macros you will have to overwrite Serialize member only to provide storing and loading each tile. (For implementing array use CObArray class...)
CArchive class doesn't support moving read/write pointer, you could flush buffers and use CArchive::GetFile()->Seek() to move the pointer, but I'm not sure if it works good....

You can also provide your own serialization based on CFile streams only: at the beginning of the file reserve some space for the header, write each tile saving its file position and then just write that info to the header... (I don't think it's enaugh complicated to describe it, if you have problems anyway just ask a detailed question)


0
 

Author Comment

by:tamnof
ID: 1181133
I've already done it all by myself almost the same as wirus' proposing.
               tahnks.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

604 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question