reading pixel color data to an array
Blitz3D Forums/Blitz3D Beginners Area/reading pixel color data to an array
| ||
Alright, so my goal here is to create a tile graphics editor that would save the image data into a basic array, ex:.tilegfx data 1,1,1,1,1,1,1,1 data 1,0,0,0,0,0,0,1 data 1,0,5,1,1,1,0,1 data 1,0,1,5,1,1,0,1 data 1,0,1,1,5,1,0,1 data 1,0,1,1,1,5,0,1 data 1,0,0,0,0,0,0,1 data 1,1,1,1,1,1,1,1 Which then could be read into the program like this: At the moment, I have the basic editor functions down pat (except for loading and saving, which will come later). But the problem I'm having is this: as the image describes, I'm having a really rough time getting the pixel grid to read the pixel rgb data from the selected tile. Here's how I have my program set up: globals and types: Global ms_x#, ms_y# Global curr_color Global curr_tile=0 Type pal Field x,y Field img,col End Type Type pix Field x,y Field px,py Field img,col Field red,green,blue End Type Type tile Field x,y Field img,frame End Type setting up the graphics: Main Loop: setup_pallete setup_pixels setup_tiles While Not KeyHit(1) ms_x=MouseX() : ms_y=MouseY() Cls DrawImage mouse,ms_x,ms_y draw_pallete(152,16) draw_pixels(16,16) draw_tiles(175,16) Color 0,0,175 : Rect 152,152,16,16 DrawImage current,152,152,curr_color Color 255,255,255 : Rect 152,152,16,16,0 If KeyHit(57) Then write_pixels Flip Wend End Setting up the palette and the grids: Drawing the palette and the grids: And now the functions used to read and write the rgb values of the tile's pixel data: What works and what doesn't seem to work: if you study the code carefully you'll note that the grid editor is made up of 8x8 tiles with 7 frames (each frame represents a shade of gray from the palette) when the user presses spacebar, the tile data is transfered to the current tile and plotted as pixels (see function write_pixel() ) But when the user selects a tile from the tileset grid, the pixel rgb data needs to be sent to the editor grid which accordingly to that rgb data, the "pixel" is set. (see function read_pixel() ) This does not seem to work at all, and the problem seems to be something with the read_pixel function which is supposed to call this action into play. the read pixel function is called like this from the draw_tiles(x,y) function : Function draw_tiles(x,y) For t.tile=Each tile DrawImage tile_grid,t\x+x,t\y+y DrawImage t\img,t\x+x,t\y+y,t\frame If ImagesOverlap(mouse,ms_x,ms_y,t\img,t\x+x,t\y+y) DrawImage sel,t\x+x,t\y+y If MouseDown(1) Then curr_tile=t\frame : read_pixels End If If curr_tile=t\frame Then DrawImage curr,t\x+x,t\y+y Next End Function this is the best I can do in describing my problem... if any further information is needed in helping me then feel free to ask. Thanks in advance! |
| ||
You are using 16-bit graphics and looking for RGB values which cannot possibly exist, such as red=119. The right way to determine the color values is to set the graphics mode, plot a color with a red value of 119 and then read it back to see what it really is. It will probably be something like 116. NOTE: I just tried this. R,G,B values of 119 read back as 112, 116, 112. I thought 16-bit color was no longer available on my PC, but it is. |
| ||
And an afterthought, be sure this is done every time the program runs. Don't do a test like I just did and then save the values 112, 116, 112 in the source code. There is no guarantee they will alway be the same on other machines. |
| ||
what's the test code that your using? I tried it with this: GetColor(ms_x,ms_y) ; get color at mouse x and y coords Text 0,0,"r: "+ColorRed()+" g: "+ColorBlue()+" b: "+ColorGreen() and the color values came up correct on both 16 and 32 bit mode |
| ||
You're in luck, I hadn't even closed the IDE.Graphics 1280, 1024, 16, 0 Color 119,119,119 Plot 0,0 GetColor 0,0 Print ColorRed() Print ColorGreen() Print ColorBlue() WaitKey This is 16-bit, full screen. If you can read back 119 then you are not really in 16-bit mode. That would be the case with windowed mode and 32-bit desktop graphics. If that is what you are running then my claim that values like 119 are unavailable does not apply. The problem must then be something else. |
| ||
thanks.. but strange, its always returning 119,119,119 again, in both modes edit: just saw the explanation below your code... so it must be something else :P |
| ||
okay, tested it in full screen mode. the values came up different.. so that solves that bit |
| ||
unfortunately that still does not seem to solve my problem here.. :( I still appreciate your input here, Floyd, I learned something from it :) but I still cant get the program to do what I want... |
| ||
Hang on, I can't really understand your problem - well I might. Can you please confirm this or explain where I'm wrong: - Your main editor is tile based. - You have a pixel editor which lets you edit each tile. - The problem is transferring the data between the tile editor and the pixel editor. Is this right? |
| ||
correct I cant get the pixel editor to change when the user clicks on a different tile |
| ||
Okay, I'll start looking at your code. |
| ||
Found the problem - and another unnecessary bit of code. At the start, you initialise your 16x16 set of pixels in setup_pixels(). Then in your two pixel changing functions (read_pixels and write_pixels) you have unnecessary for loops which are causing the problems. read_pixels() See how you have the two for loops here (i.e. x = 1 to 16 and y = 1 to 16)? This means that for each individual pixel, your program will go through every pixel in the tile. You don't need these loops because the for-each loop will go through each pixel. Essentially, because of these loops, each pixel would be set to the value of {16,16} in the tile. In fact, this was another problem. When indexing pixels like this in Blitz, the first pixel is 0, not 1. So, the pixels actually range from {0,0} to {15,15}. When you call GetPixel on {16,16}, which is the last thing that happens before your loops move on, it won't find anything because pixel {16,16} doesn't exist! That's why all of your pixels were being set to 'Transparent' - the RGB values from the non-existent pixel would come out to 0, 0, and 0. This is what was causing your program 'not' to read tiles. After taking out the two inner loops, px and py will be useless. There are two ways you can resolve this. The first is to use a similar method to your 'write_pixels' function: GetColor px\x / 8, px\y / 8 Alternatively, in your initialisation loop, you can set the px and py values of each pixel and use these. This will save on divisions, but this doesn't really matter anyway. Working read_pixels() function: Now, in your 'write_pixels' function: You also have two unnecessary for loops here. These don't affect the results though - they just mean each pixel is written 256 times to the same spot... So I've taken them out as well: As far as I can see, everything is working fine now. Be careful about putting in loops that shouldn't be there. If you haven't understood my explanation, let me know and I'll try again. |
| ||
Thanks a bunch, Serpant! :) I'll be looking over your explanation and changes when I get the time to do so. Your help here is greatly apreciated! :) |
| ||
alright, so now I got the time to look over everything. It makes perfectly good sense about the for loops causing the problems so your explanation was a perfect ace :) I guess I have a nasty habit of using these loops when it comes to programming :P Again, thanks! :) if I make something with this, I'll credit you for your help ;) |
| ||
You are using 16-bit graphics and looking for RGB values which cannot possibly exist, such as red=119. Not strictly true. In Blitz, if you're in 16-bit mode, it'll still return 24-bit colour values. However, it'll simply average them out. So in other words, it'll take the 16-bit colour of the pixel and return the actual 24-bit colour data. |
| ||
And make sure your in full screen, as i don't believe blitz properly does 16 bit mode, in windowed mode. |
| ||
And make sure your in full screen, as i don't believe blitz properly does 16 bit mode, in windowed mode. Yep, quite so. In windowed mode, Blitz is forced to render at whatever the Windows desktop colour depth is, and the colour depth parameter of Graphics() is overridden. |