Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Image Memblock tutorial

Author
Message
Manic
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Completely off my face...
Posted: 17th Jul 2007 18:50
I just found this lurking around on some old webspace of mine, I know I didn't write it, but I don't know who did, so if anyone recognises it please let it be known.

This helped me to code a image difference filter once for use with webcam tracking, i never got to use it in the end though.

here follows;


Images and Memblocks


What is a memblock?
Memblocks are blocks of memory allocated by the user to store any type of date. For this discussion, a memblock will be a chunk of memory containing an image.

Why use memblocks?
Memblocks allow you to access data which is stored directly in memory. This direct access is very quick, and that is useful when you need real-time effects and speed is an issue.

How do you use memblocks?
Because we will be using image data to demostrate memblocks, we will use the command make memblock from image. It's syntax is as follows:

make memblock from image memblock number, image number
make memblock from image 1, 5


The memblock number is used just like an object number. The image number is the image that the memblock will be constructed of. Now that we have a memblock containing the data of the image, how do we access that data? Whether you load a jpg, pcx, or bmp image, it's all stored the same way inside the memblock. There's no messy headers to mess with, which simplifies things greatly. First thing you should know is that a dword is 4 bytes. The first 12 bytes of data in the memblock contain info about the image.

Bytes:
0-3 = image width
4-7 = image height
8-11 = image depth

To retrieve this data, use the memblock dword() command.

width = memblock dword(1, 0)
height = memblock dword(1, 4)
depth = memblock dword(1, 8)

From this point on, the rest of the data in the memblock is the pixel information. Each color value is one byte. We typically think of the three primary colors are red, green, blue. But in the memblock, the colors are in reverse order to what we know. So starting at byte 12 (first byte after depth) we can extract the pixel's color information.

B = memblock byte(1,12)
G = memblock byte(1,13)
R = memblock byte(1,14)
A = memblock byte(1, 15)

These color components make up the color value for the first pixel in the image.(upper left corner) The "A" value is the alpha level of the pixel. B, G, R are the blue, green, and red channels, respectfully. Since we know the image's width and height, we can create a simple nested FOR loop to read in colors of the entire image.

for x = 1 to width
for y = 1 to height
location = ((y-1)*width + x - 1)*4 + 12
B = memblock byte(1,location)
G = memblock byte(1,location+1)
R = memblock byte(1,location+2)
A = memblock byte(1, location+3)
next y
next x

Now obviously, this loop would serve no real purpose, because you're not doing anything with the values after you read them in. This is just an example to show you how you can easily read the data of the entire memblock of an image. Now for an explanation of the "location" variable. Given the X and Y coordinate for a pixel in the image, the correct memory location is calculated. Each pixel is every 4 bytes, because it takes 4 bytes of memory to store the color data of one pixel. 12 is added to the end of the equation as an offset, because the first actual 12 bytes of data isn't pixel information, its the width, height, depth data.
Now lets say you want to edit the image. For example, let's set the first pixel to a pink color. For this we use write memblock byte or write memblock dword.

write memblock byte 1, 12, 128 : `blue channel
write memblock byte 1, 13, 28 : `green channel
write memblock byte 1, 14, 255 : `red channel
write memblock byte 1, 15, 0

As far as I've been able to tell, the alpha value has shown no meaning. But if it does, it'll have an affect with the image's transparency. An alternative way of writing the pixel data is:

write memblock dword 1, 12, rgb(255,28,128)

The command, rgb(), returns a dword size value of a color made up of the red, green, and blue channel values specified. This will automatically write the proper numbers of each color channel to the appropriate bytes for you. The alpha value will be sent to either 0 or 255.

And finally, after we've done all the changes we want to the image's data, we must create a new image from that data using the command make image from memblock.

*note the order of the image number and memblock number. The DBP manual states that the first parameter is the memblock number. This is not true, the command expects the image number first, then the source memblock number.

make image from memblock image number, memblock number
make image from memblock 3, 1

You can overwrite the existing image number you created the memblock from, or create a whole new image. The source code below will load an image, create a memblock from it, change half the pixels of the image in the memblock to a random color, then create a new image. (You can overwrite the original image if you wish. This does not permanately overwrite your loaded image, the effect is only in memory. No actual data is ever written to the existing image file itself)


sync on

REM load an image
load image "fog.bmp", 4

REM create a memblock from the image
make memblock from image 1, 4

REM get the image's width and height
width = memblock dword(1,0)
height = memblock dword(1,4)

for x = 1 to width/2
for y = 1 to height
location = ((y-1)*width + x - 1)*4 + 12
REM set each pixel in the image to a random color
write memblock dword 1, location, rgb(rnd(255),rnd(255),rnd(255))
next y
next x

REM create a new image from the memblock data
make image from memblock 3, 1

REM display the new image
repeat


sprite 1,mousex(), mousey(), 4
sprite 2,mousex()+width+5, mousey(), 3

sync
until spacekey()





hope this helps people

Manic

I don't have a sig, live with it.
FROGGIE!
20
Years of Service
User Offline
Joined: 4th Oct 2003
Location: in front of my computer
Posted: 17th Jul 2007 20:40
Thats a very good tutorial, well done to whoever wrote it.
Unlordly
16
Years of Service
User Offline
Joined: 17th Jul 2007
Location:
Posted: 17th Jul 2007 21:05
This is a great tutorial, its helping me with loading a custom made image format so no-one can copy them.
Vidiot
17
Years of Service
User Offline
Joined: 15th May 2006
Location: TN
Posted: 19th Jul 2007 18:02
Memblocks have been a bit of a mystery to me, but especially as it replates to images. This is very helpful! Thanks!

The answer to Life, the Universe, and Everything? "Tea for Two". Deep Thought was Dyslexic.

Login to post a reply

Server time is: 2024-04-27 01:26:06
Your offset time is: 2024-04-27 01:26:06