Solved

Accessing pixel data of a bitmap

Posted on 2001-08-26
5
621 Views
Last Modified: 2013-11-20
I have recently come across the need to create some custom controls. One of these controls is basically an M x N area that has a bitmap blitted into it. However for speed reasons I am performing all rendering to an area of memory somewhere else at a colour depth of 8bpp. In order for my user to see what I am rendering to this off screen memory area I need to somehow copy this data to either:

a) The window that is going to display it
b) To a bitmap that I can then blit to the window

I also need to use this same techique to render bitmaps that the user loads from disk.

The software that I am currently creating is a tile map editor with custom functionality. The currently available editors will not handle what I need this editor to do, so I am forced to write my own. :(

So in summary I need:

1) Create a CBitmap from a chunk of memory at a colour depth of 8bpp. I guess I could use CBitmap::CreateBitmapIndirect()
2) Since I dont want to have to keep re-creating and destroying the above bitmap every time I change the off screen bitmap I need to find a way of somehow getting direct access to the pixel data of the created bitmap. However creating a CBitmap from a BITMAP copies the data pixel data and does not use the memory area as assigned in the BITMAP structure.

Since this software is not commercial I am willng to accept pointers to good already pre-written classes or libs that allow creation of a bitmap and allow direct access to its pixel data and / or palette for 8bpp modes. I've looked at CDIB but it doesn't appear to support the functionality that I need. Has anyone any experience with WinG, would this provide this kind of functioanlity, remembering that this is going to operate on parts of controls within dialogs?







0
Comment
Question by:matth012098
  • 3
  • 2
5 Comments
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
I'm not sure that I understand the entire question, but I will provide some background info and then try to address the numberd bullet items:

* There is a very simple way to get a bitmap to be displayed in a window.  Create a CSTATIC control and set its SS_BITMAP style.  Then you can call CStatic::SetBitmap and it will be displayed instantly.

* Because modern PCs are very fast and have lots of memory, you probably don't need to worry about double-buffering or manully doing off-screen manipulation.  Just waste some RAM by making temporary duplicates of the bitmaps.  Consider that even a huge 100K bitmap is using up only 1/2560-th (about 0.03%) of the computer's 256MB of RAM.  A drop in the bucket.

* You talk about directly accessing the binary image data.  That is rarely needed.  It is best to stick with GDI commands since they are so flexible.  Now I know of cases where "getting your hands dirty" with the individual bits can make sense (see http://home.earthlink.net/~danrollins/ee/FastBmpRotation.htm ) but you are usually best off use the wealth of drawing commands listed under the CDC class.

* You talk about 8-bpp images.  These turn out to be the hardest to manipulate because of the extra palette processing involved.  A good "getting started" idea would be to work with 24-bpp images until you get a real handle on the issues and techniques, then try switching to 8-bpp images so you can layer-in the palette stuff.

=-=-=-=-=-=-
>> 1) Create a CBitmap from a chunk of memory at a colour depth of 8bpp...

Just use CreateDIBitmap, followed by SetDIBits.  The CDIBSectionLite class at
   http://www.codeguru.com/bitmap/DIBSectionLite.shtml
and others code at
   http://www.codeguru.com/bitmap/index.shtml
will provide some useful utility to help you get started.  If you want some code to create a 256-color bitmap, just ask.

>> 2) Since I dont want to have to keep re-creating and destroying the above bitmap...

No need to create/destroy... just maintain that offscreen bitmap in a CMemoryDC.  Use BitBlt to transfer image data.  Anyway, creating/destroying is no big deal.  What's a couple of milliseconds between freinds?

>>However creating a CBitmap from a BITMAP copies the data pixel data and does not use the memory area as assigned in the BITMAP structure

This is where i think you are penny-wise and pound-foolish.  You need not (and should not) write to the actual storage area of the bitmap.  Instead, use BitBlt to transfer the bitmap data into a temporary CMemoryDC, use some GDI commands to modify it, then BitBlit it back.

=-=-=-=-=-=-=-=--=
Bitmap manipulation can be a complex issue and there is a steep learning curve involved.  Please feel free to ask for clarification on anything.

-- Dan
0
 
LVL 3

Author Comment

by:matth012098
Comment Utility
I wrote a system that emulates some of the graphical capabilities of a well known 2D games console. I then wrote a very fast 3D game engine that runs under both emulation and on the target hardware. Unfortunately to create a game world that utilises this fast rendering engine I need to create a editor that allows editing of its specialised map data format. For this thing to work seamlessly I need to take the emulated render output and somehow map it to a window or bitmap. With this in mind I cannot use GDI to perform the texture mapping and what not that the source renderer does. I guess I could create a bitmap from the emulated render ouput (which is in 8 BPP, but I can convert this to the users current display colour resolution on the fly) and then blit that to the window.
This will however entail creating, blitting and deleting the bitmap each time the render output is changed. Is the process of creating, deleting the bitmap fast and will it cause the heap to become fragmented badly?


0
 
LVL 49

Accepted Solution

by:
DanRollins earned 300 total points
Comment Utility
>>Is the process of creating, deleting the bitmap fast and will it cause the heap to become fragmented badly?

There is no particular reason to think so.  In one of my suggestions, you have just a single off-screen CD and bitmap, so there is no reason to worry about fragmented memory allocations.

I think this would be a good situation to try it using the techniques I suggested.  Then if you find that you have a performance problem, you can look for ways to improve it.  Nothing about these techniques lock you into doing something a certain way.

-- Dan
 
0
 
LVL 3

Author Comment

by:matth012098
Comment Utility
I've ended up creating my own CXBitmap class. This class basically keeps it's own area of pixel memory and a palette for palettised modes. The user can create any format bitmap that they like and gain direct access to its pixels / palette. Whenever changes are made the user calls Refresh() to convert the pixels to a CBitmap internally, or Refresh(CDC *pDC) to rebuild the whole bitmap that is compatible with the supplied DC. The class automatically converts the pixel memory area and palette to other colour depths during refresh.

Thanks for your help
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Excellent!  If you run into any snags, feel free to make a post here.  I might be able to be more help.

-- Dan
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now