clickable bitmap colour problems
-
People on this message board did try to help me out with this before, I got frusterated and decided to leave it for a while, then come back to it, thinking it would be easier to fix. I have a bitmap, representing 92 of the elements from the periodic table. each of these 92 elements must have a distinct colour (using r, g, b values). I also have a .txt file containing the element symbol, name, and each of the rgb values, in the format: Hydrogen,H,1,49,0,0 ... When the user clicks on the bitmap, I obtain the r, g, b values at the point of the click, and use those values to determine which element the user clicked on. So, here's the problem: When the user clicks on Hydrogen, for example, with a colour setting of 16-bits, everything works fine. But, if i change the colour settings of my monitor to 24 or 32 bits, my program reports that the user clicked on the colour 51, 0, 0. I am using photoshop (new to using this) to edit the colours of my bitmap. Still working with the Hydrogen example, photoshop says that hydrogen is set to have the colour 51, 0, 0 (no matter what my colour settings are). So I did change the entry in my text file to reflect this colour, but when I run my program, it reports that it is, in fact 49,0,0 in 16-bit and 51,0,0 for 24 and 32 bit colour. This is how I'm obtaining the colour in my code:
COLORREF crColourAtPoint = 0;
...
crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y);CString values; values.Format("Red: %d\\nGreen: %d\\nBlue: %d", GetRValue(crColourAtPoint), GetGValue(crColourAtPoint), GetBValue(crColourAtPoint)); AfxMessageBox(values);
-
People on this message board did try to help me out with this before, I got frusterated and decided to leave it for a while, then come back to it, thinking it would be easier to fix. I have a bitmap, representing 92 of the elements from the periodic table. each of these 92 elements must have a distinct colour (using r, g, b values). I also have a .txt file containing the element symbol, name, and each of the rgb values, in the format: Hydrogen,H,1,49,0,0 ... When the user clicks on the bitmap, I obtain the r, g, b values at the point of the click, and use those values to determine which element the user clicked on. So, here's the problem: When the user clicks on Hydrogen, for example, with a colour setting of 16-bits, everything works fine. But, if i change the colour settings of my monitor to 24 or 32 bits, my program reports that the user clicked on the colour 51, 0, 0. I am using photoshop (new to using this) to edit the colours of my bitmap. Still working with the Hydrogen example, photoshop says that hydrogen is set to have the colour 51, 0, 0 (no matter what my colour settings are). So I did change the entry in my text file to reflect this colour, but when I run my program, it reports that it is, in fact 49,0,0 in 16-bit and 51,0,0 for 24 and 32 bit colour. This is how I'm obtaining the colour in my code:
COLORREF crColourAtPoint = 0;
...
crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y);CString values; values.Format("Red: %d\\nGreen: %d\\nBlue: %d", GetRValue(crColourAtPoint), GetGValue(crColourAtPoint), GetBValue(crColourAtPoint)); AfxMessageBox(values);
I think you're going about this the wrong way ... why do you pick depending on the color ? Why can't you just pick depending on the pixel position ? i.e. when the user clicks on one particular element "space" you only need to check it the mouse is inside the "space" ?
Maximilien Lincourt "Never underestimate the bandwidth of a station wagon filled with backup tapes." ("Computer Networks" by Andrew S Tannenbaum )
-
People on this message board did try to help me out with this before, I got frusterated and decided to leave it for a while, then come back to it, thinking it would be easier to fix. I have a bitmap, representing 92 of the elements from the periodic table. each of these 92 elements must have a distinct colour (using r, g, b values). I also have a .txt file containing the element symbol, name, and each of the rgb values, in the format: Hydrogen,H,1,49,0,0 ... When the user clicks on the bitmap, I obtain the r, g, b values at the point of the click, and use those values to determine which element the user clicked on. So, here's the problem: When the user clicks on Hydrogen, for example, with a colour setting of 16-bits, everything works fine. But, if i change the colour settings of my monitor to 24 or 32 bits, my program reports that the user clicked on the colour 51, 0, 0. I am using photoshop (new to using this) to edit the colours of my bitmap. Still working with the Hydrogen example, photoshop says that hydrogen is set to have the colour 51, 0, 0 (no matter what my colour settings are). So I did change the entry in my text file to reflect this colour, but when I run my program, it reports that it is, in fact 49,0,0 in 16-bit and 51,0,0 for 24 and 32 bit colour. This is how I'm obtaining the colour in my code:
COLORREF crColourAtPoint = 0;
...
crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y);CString values; values.Format("Red: %d\\nGreen: %d\\nBlue: %d", GetRValue(crColourAtPoint), GetGValue(crColourAtPoint), GetBValue(crColourAtPoint)); AfxMessageBox(values);
I would agree with Maximilien in that there is a better way to go. But first the problem you are experiencing is caused by the fact you are saving the image in photoshop as a full RGB color range of 24 bits. When you go to display it on a system that cannot support that color range, the colors are down converted to the displays setting range (16 bit in this case). The solution is to save the image in Photoshop using smaller palatte. Try using Image->Mode->Index color on the menu and save to a 256 color system palatte to get you image colors downselected. Back to your method... I would suggest you look at an article submitted last month here in CodeProject. I can't remember the name of the author but the program name was something like "Periodic Table" or PTE table.. where the author used some very good techniques to accomplish the same task of locating the periodic table element from the mouse position. Hope this helps. Art
-
I think you're going about this the wrong way ... why do you pick depending on the color ? Why can't you just pick depending on the pixel position ? i.e. when the user clicks on one particular element "space" you only need to check it the mouse is inside the "space" ?
Maximilien Lincourt "Never underestimate the bandwidth of a station wagon filled with backup tapes." ("Computer Networks" by Andrew S Tannenbaum )
Either way, I'd still have to record a bunch of information, whether it be the location of each elements space, or the colour of the element. A few months ago I had discussed different ways of doing this with a bunch of people on here, and after a few days of going through the different options, it was decided that the clickable bitmap approach would be the best option. So I did it that way. I'm just running into a problem when switching down to 16 bit colour, as I expected. I thought that just by switching my monitor settings to 16 bit, then re-colouring the bitmap, and putting the new colour values into my .txt file my problem would be solved. I figured that if I did it that way, the colour values would remain constant between 16 bit and 24/32 bit colour, but I was wrong. I need to know whether I'm just selecting the wrong colours, or whether there's a way to determine from within my code what colour settings the user has for their monitor, or even if this problem is fixable or not.
-
People on this message board did try to help me out with this before, I got frusterated and decided to leave it for a while, then come back to it, thinking it would be easier to fix. I have a bitmap, representing 92 of the elements from the periodic table. each of these 92 elements must have a distinct colour (using r, g, b values). I also have a .txt file containing the element symbol, name, and each of the rgb values, in the format: Hydrogen,H,1,49,0,0 ... When the user clicks on the bitmap, I obtain the r, g, b values at the point of the click, and use those values to determine which element the user clicked on. So, here's the problem: When the user clicks on Hydrogen, for example, with a colour setting of 16-bits, everything works fine. But, if i change the colour settings of my monitor to 24 or 32 bits, my program reports that the user clicked on the colour 51, 0, 0. I am using photoshop (new to using this) to edit the colours of my bitmap. Still working with the Hydrogen example, photoshop says that hydrogen is set to have the colour 51, 0, 0 (no matter what my colour settings are). So I did change the entry in my text file to reflect this colour, but when I run my program, it reports that it is, in fact 49,0,0 in 16-bit and 51,0,0 for 24 and 32 bit colour. This is how I'm obtaining the colour in my code:
COLORREF crColourAtPoint = 0;
...
crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y);CString values; values.Format("Red: %d\\nGreen: %d\\nBlue: %d", GetRValue(crColourAtPoint), GetGValue(crColourAtPoint), GetBValue(crColourAtPoint)); AfxMessageBox(values);
Windows remaps colours to best match the available palette. 4- and 8-bit modes are palettized; you can specify the palette you want to use by calling RealizePalette. You should do this in response to a WM_QUERYNEWPALETTE or WM_PALETTECHANGED message. In 16-bit mode, the available range of colours is typically limited to 5 bits per pixel for red and blue colour information and either 5 or 6 bits per pixel for green colour information. The colour you request is mapped onto the bits available; when you request the colour of the pixel, the value is mapped back onto the 0 to 255 range. This conversion can be subject to rounding errors. If we say that Red is limited to 5 bits of representation, that gives us values 0 to 31. Mapping your 51 in the 0-to-255 to this range gives 6.375, rounded down to 6. When getting the pixel colour, the actual 6 in the 5 bit world now becomes 48 in the 8 bit world. I assume that Windows isn't doing a direct mathematical conversion, probably factoring gamma into the equation as well, which leads to the specified 49. Anyway, you can't rely on the colour retrieved from GetPixel being the colour you set. It's better to work with areas of an image than with colours, if possible. Alternatively, work directly with the original bitmap, rather than the on-screen representation of it.
-
I would agree with Maximilien in that there is a better way to go. But first the problem you are experiencing is caused by the fact you are saving the image in photoshop as a full RGB color range of 24 bits. When you go to display it on a system that cannot support that color range, the colors are down converted to the displays setting range (16 bit in this case). The solution is to save the image in Photoshop using smaller palatte. Try using Image->Mode->Index color on the menu and save to a 256 color system palatte to get you image colors downselected. Back to your method... I would suggest you look at an article submitted last month here in CodeProject. I can't remember the name of the author but the program name was something like "Periodic Table" or PTE table.. where the author used some very good techniques to accomplish the same task of locating the periodic table element from the mouse position. Hope this helps. Art
Art Friesz wrote: using Image->Mode->Index color on the menu and save to a 256 color system palatte I am using indexed colour in photoshop. Art Friesz wrote: would suggest you look at an article submitted last month here in CodeProject. I can't remember the name of the author but the program name was something like "Periodic Table" or PTE table This article was written by one of the guys that was helping me before, back in september. He started that article because I was asking about it back then. Seeing as I had never done anything with colours/bmp's in my applications before, I ended up needing quite a bit of help, as i guess I still do.
-
I would agree with Maximilien in that there is a better way to go. But first the problem you are experiencing is caused by the fact you are saving the image in photoshop as a full RGB color range of 24 bits. When you go to display it on a system that cannot support that color range, the colors are down converted to the displays setting range (16 bit in this case). The solution is to save the image in Photoshop using smaller palatte. Try using Image->Mode->Index color on the menu and save to a 256 color system palatte to get you image colors downselected. Back to your method... I would suggest you look at an article submitted last month here in CodeProject. I can't remember the name of the author but the program name was something like "Periodic Table" or PTE table.. where the author used some very good techniques to accomplish the same task of locating the periodic table element from the mouse position. Hope this helps. Art
OK, if it were me and I just wanted to get this problem solved I would do one of the following: Option 1) Compare on a range of RGB values. Example: allow a match of the RGB color provided in the txt file if the mouse pickuped a value within say 5 of each of the RGB values. In other words Hydrogen would be matched if the mouse picked up a R value between 51-5=46 and 51+5=56 and G and B was between 0 and 5. or Option 2) (the preferred way) Change your text file to include the percentages of the grid they occupy in the image and then pick up the mouse position on the window and convert it to percentage of the window width and height, then match the point in the rectange: (Element Name, Element symbol, atomic no., x1,x2,y1,y2) Example: text file would look like this: Hydrogen,H,1,0,6,0,8 Helium,He,2,0,6,10,18 ... When you read in the txt file use the x1, x2.. for the coordinates in a CRect. Use CRect::PtInRect()to look for a match. Art
-
OK, if it were me and I just wanted to get this problem solved I would do one of the following: Option 1) Compare on a range of RGB values. Example: allow a match of the RGB color provided in the txt file if the mouse pickuped a value within say 5 of each of the RGB values. In other words Hydrogen would be matched if the mouse picked up a R value between 51-5=46 and 51+5=56 and G and B was between 0 and 5. or Option 2) (the preferred way) Change your text file to include the percentages of the grid they occupy in the image and then pick up the mouse position on the window and convert it to percentage of the window width and height, then match the point in the rectange: (Element Name, Element symbol, atomic no., x1,x2,y1,y2) Example: text file would look like this: Hydrogen,H,1,0,6,0,8 Helium,He,2,0,6,10,18 ... When you read in the txt file use the x1, x2.. for the coordinates in a CRect. Use CRect::PtInRect()to look for a match. Art