Solved

Accessing pixel data of a bitmap

Posted on 2001-08-26
5
644 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
[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
  • 3
  • 2
5 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 6427202
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
ID: 6427280
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
ID: 6428035
>>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
ID: 6428543
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
ID: 6431081
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

617 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