News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Bitmap editing in memory?

Started by i Z !, February 18, 2015, 11:20:17 PM

Previous topic - Next topic

i Z !

I'm trying to make a program, with which you could change color table of a 16 color bitmap and display it on click...
The API way seems quite complicated.. I just want to change some bytes of images, which are below 700KB. Is there maybe some other way to 'put' an image from memory onto a window?

Thanks in advance,
iZ!

dedndave

the ChooseColor dialog is pretty easy to use - easier than anything you might cobble together   :t

here's an example on the old forum by MichaelW

http://www.masmforum.com/board/index.php?topic=15777.msg130280

especially nice if you are working with 16-color images

i Z !

Dave: I guess but I was thinking of making three slidebars representing RGB values and with each change, the color table value of the selected color would accordingly change and the picture would be redrawn.

dedndave

it's a lot simpler to use ChooseColor, let me tell you - lol

you do know that you can drag these 2 tools around to pick a color
the numbers are displayed in the edit boxes and change as you move the tools

i Z !

Ok.. But anyway, regardless of how I get the color, how could I then modify the bitmap's color table while the bitmap is sitting in memory? I know what certain bytes represent..
I did a sum up from the site that I mentioned in my first topic (in case someone's interested):


bfType 2 The characters "BM"
bfSize 4 The size of the file in bytes
bfReserved1 2 Unused - must be zero
bfReserved2 2 Unused - must be zero
--10
bfOffBits 4 Offset to start of Pixel Data


--14


biSize 4 Header Size - Must be at least 40
--18
biWidth 4 Image width in pixels
biHeight 4 Image height in pixels
biPlanes 2 Must be 1
--28
biBitCount 2 Bits per pixel - 1, 4, 8, 16, 24, or 32
biCompression 4 Compression type (0 = uncompressed)
biSizeImage 4 Image Size - may be zero for uncompressed images
biXPelsPerMeter 4 Preferred resolution in pixels per meter
biYPelsPerMeter 4 Preferred resolution in pixels per meter
--46
biClrUsed 4 Number Color Map entries that are actually used
biClrImportant 4 Number of significant colors

--54


The Color Table

If we are dealing with images having a bit depth of 8 or less, then the pixel data
is actually an index into a color palette. For instance, in a 4-bit image there are
a maximum of 16 colors in the palette. If the data for a particular pixel is, say,
9, then the color that is used for that pixel is given by the tenth entry in the
table (because the numbering starts with 0 and not 1).

In all versions of BMP files starting with Version 3 (Win3x), the color entries
occupy 4 bytes each so that they can be efficiently read and written as single
32-bit values. Taken as a single value, the four bytes are ordered as follows:
[ZERO][RED][GREEN][BLUE]. Due to the Little Endian format, this means that the Blue
value comes first followed by the green and then the red. A fourth, unused, byte
comes next which is expected to be equal to 0.

If we are dealing with 16-bit or 32-bit images,
then the Color Table contains a set of bit masks
used to define which bits in the pixel data to
associate with each color. Note that the original
Version 3 BMP format did not support these image
types. Instead, these were an extension of the
format developed for WindowsNT. For both the
16-bit and the 32-bit variants, the color masks
are 32-bits long with the green mask being first
and the blue mask being last. In both cases the
bit masks start with the most significant bits,
meaning that for the 16-bit images the least significant
two bytes are zero. The format requires that the
bits in each mask be contiguous and that the masks
be non-overlapping. The most common bit masks for
16-bit images are RGB555 and RGB565 while the most
common bitmasks for 32-bit images are RGB888 and
RGB101010.

If we are dealing with a 24-bit image, then there is no Color Table present.

i Z !

I mean - I know how to modify the color table, but how to display the bitmap to a window from memory..

dedndave

there are pre-defined structures for the header part of a bitmap - best to use those   :t

BITMAPFILEHEADER, BITMAPINFOHEADER, RGBQUAD are the pertinant structures

https://msdn.microsoft.com/en-us/library/dd183374%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/dd183376%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/dd162938%28v=vs.85%29.aspx

you can read the file headers into the structures directly, using ReadFile
and edit the palette, as desired

another way to go, better if you want to display the image, is to use the GDI functions
you can LoadBitmap to get a HBITMAP handle
then, select the bitmap into a DIB section (CreateDIBSection)
from there, you can get the palette using GetDIBColorTable and update it with SetDIBColorTable

dedndave

you are just getting started with windows programming, so there is much to learn to get going

you should do some reading on WM_PAINT, device contexts, painting and drawing, and so on
Alfonso did a graphics tutorial recently that might be helpful...

http://masm32.com/board/index.php?topic=1856.msg19118#msg19118

to use all that, of course, you need to learn about GUI window apps

Iczelion's tutorial can help with that

i Z !

Ok. Thanks for your help. I'll give it a go to see if it's not too much work:)
Otherwise I'll use X11-Basic for this..

dedndave

you won't learn anything, that way   :biggrin:

attached is a simple window program to get you started
the main elements of creating a window:
1) WndProc function
2) register the window class
3) CreateWindow call
4) message loop


add to that, the manifest and InitCommonControlsEx, and the resource file, and you are on your way   :t

rrr314159

Hello iZ,
Quote...how to display the bitmap to a window from memory..
I know 2 ways to display edited memory bitmaps. One is the "API way", which is not too complicated; as dedndave mentioned it involves CreateDIBSection, etc ... final step is "BitBlt". I can go thru those steps if you want. This way, you write directly to the screen. The other is to save your changed picture as a BMP to disk, then display that any convenient way; even Windows Photo Viewer. You can automate the process so it's not too hokey. Let me know if you want more details about either technique.
I am NaN ;)

i Z !

Dave: Thanks it seems a bit closer to me now..:) I only ran through it once.. Still not sure though.. I'll check it out again today.

rrr: Yea, I was even thinking of creating a BMP file on virtual disk in RAM(it used to be possible in DOS, I never used it in Windows) and then use the 'showbmp.asm' example..

Thanks both for your support

rrr314159

iZ,

Yes that was the first way I did it. Really no need for virtual disk, the hard disk is plenty fast enough. I know it's ugly - here's your BMP in memory, there's the video mem right across the bus, and instead you go all the way out to disk and back - but it works OK. When you've absorbed dedndave's example you can graduate to using API's. The reason u need CreateDIBSection etc is, the video resolution and bit depth is changeable and complicated. If u have direct access to video mem (as in the old days) it's hard to figure out where the rows/columns/pixels are, and it all changes when the user modifies display properties. Not to mention virtual memory ... Better to let Windows figure it all out for u. Also the double-buffer approach can eliminate flicker / update problems. Sometimes, Bill knows what he's doing! :biggrin: Good luck , !
I am NaN ;)

i Z !

Quote from: dedndave on February 19, 2015, 04:55:11 AM

another way to go, better if you want to display the image, is to use the GDI functions
you can LoadBitmap to get a HBITMAP handle
then, select the bitmap into a DIB section (CreateDIBSection)
from there, you can get the palette using GetDIBColorTable and update it with SetDIBColorTable

I'm starting to get this now..:), thanks..

dedndave

later today, i will post a little program in another thread that uses a DIB section
(if i have time to finish it)