Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a screen image from TColors and intensities (in Delphi)

I have a (spectrographic profile) data set of Wavelength (x-axis) and Intensity (y-axis, in arbitrary units that can have different ranges...)

I want to convert this numeric data to a graphical view as shown at the bottom of the image below.

But, I've never done anything in Delphi (2010) with Canvas's, TImages, bitmaps, or whatever way I'd get this to the screen.

(Obviously, if I can convert my data to one row of image pixels, I then simply copy that row as many times as needed for my desired image height.)

Can anyone point me in the right direction or supply sample code that traverses the x,y values, creating the color image? I'm hoping my solution will allow me (or the user) to adjust levels (contrast, brightness).

Thanks in advance.

alt text

Related SO posts: Algorithm to convert any positive integer to an RGB value

Convert light frequency to RGB?

like image 703
RobertFrank Avatar asked Sep 14 '10 15:09

RobertFrank


2 Answers

Well, it looks to me like your wavelengths are hues, and your intensity is another word for brightness. Getting the right colors would be a really simple task if only you had a model that represents colors in terms of hue and brightness and a way to convert between it and RGB... :-)

Displaying the colors is actually very simple. You can use a standard TImage component on a form. Once you work out what TColor value goes at a certain position, you can set it with

image.Canvas.Pixels[x, y] := aColor;

EDIT: How to map wavelength to hue:

This is a little tricky since the left hand side of your spectrum seems to be the violet, with the red on the right. In HSL, red is at the 0 position. You're going to have to invert your X axis so red is 0 and violet is high. You can get this by basically saying value := MAX_VALUE - value;

Then you need to calibrate the line. Set the wavelength corresponding to full red equal to 0, and the far blue end equal to whatever its corresponding hue is. (If you can convert a wavelength to a TColor and then a TColor to HSL that shouldn't be difficult to calculate.) That's your range, and you need to normalize all wavelengths to fit into that range.

Just eyeballing it, it looks to me like the left end of your example spectrum is at around 270 degrees hue on the color wheel, which equates to 192 on a scale of 0--255. So take your spectrum from red to blue--again, remember red is LOW, not HIGH--and normalize it to the range 0--192 (or whatever the actual high value is) and you've got your H value.

Also, if you've got some colors on the right end of your color line that go beyond full red towards purple a little, then you'll have a negative hue, which wraps around back to 255.

like image 190
Mason Wheeler Avatar answered Oct 15 '22 11:10

Mason Wheeler


You have exactly what you need in that Delphi library from efg.
But you really should read the article on Visible Light Spectrum first: Spectra.
"The purpose of this program is to display RGB colors as a function of wavelength for visible light (380 to 780 nm)."

The only modification you have to add is to modulate for intensity. But as Mason suggested, going through HSI representation makes it easy to adjust the Intensity: so a quick'n'dirty solution is, once you get the RGB from wavelength, to convert to HSI, adjust I than convert back to RGB.

like image 31
Francesca Avatar answered Oct 15 '22 11:10

Francesca