convert Color in C# .NET to long for a dll

P

Peter Webb

Sorry, couldn't find this on Google, at least not for C#, or in Help

I am calling cards.dll which accepts a long for color from within a C#
program.

How to I convert (say) Color.Red into a long for the DLL?

TIA
 
P

Peter Duniho

Peter said:
Sorry, couldn't find this on Google, at least not for C#, or in Help

I am calling cards.dll which accepts a long for color from within a C#
program.

How to I convert (say) Color.Red into a long for the DLL?

That all depends on the format of the long expected by the DLL. But,
Color.ToArgb() _might_ do what you want.

If you want a better answer, you need to be more specific about how the
long expected by your DLL describes a specific color.

Pete
 
J

Jeff Gaines

Sorry, couldn't find this on Google, at least not for C#, or in Help

I am calling cards.dll which accepts a long for color from within a C#
program.

How to I convert (say) Color.Red into a long for the DLL?

TIA

I use this:

private int RGBColour(Color colTemp)
{
int intColour = colTemp.B * 255 * 255;
intColour += colTemp.G * 255;
intColour += colTemp.R;
return intColour;
}

The long variable types should be int in C#.
 
P

Peter Webb

Thanks to both of you.

I am elsewhere in the code at the moment; when I open this part up again I
will do some testing as per the suggestions.
 
T

Tim Roberts

Jeff Gaines said:
private int RGBColour(Color colTemp)
{
int intColour = colTemp.B * 255 * 255;
intColour += colTemp.G * 255;
intColour += colTemp.R;
return intColour;
}

That's not correct. The color components are integers ranging from 0 to
255. You need to multiply them by 256 to shift them into place, not by
255.

More efficient yet would be:

int intColor = (colTemp.B << 16) | (colTemp.G << 8) | colTemp.R;
 
J

Jeff Gaines

That's not correct. The color components are integers ranging from 0 to
255. You need to multiply them by 256 to shift them into place, not by
255.

I'm not shifting them, I'm making an integer out of the individual colour
components. I can promise you it has worked for many years :)
More efficient yet would be:

int intColor = (colTemp.B << 16) | (colTemp.G << 8) | colTemp.R;

I'm sure there are better ways, as Peter said Color.ToArgb() might do it,
but this function was written long before .NET was a twinkle in anybody's
eye!
 
P

Peter Duniho

Jeff said:
I'm not shifting them, I'm making an integer out of the individual
colour components. I can promise you it has worked for many years :)

No doubt the error in the algorithm is hard to perceive in real-world
usage. But it's there.

Of course, it all does depend on how the integer is consumed. But I
have _never_ seen any code that has the reverse algorithm (i.e. divide
by 255 iteratively to retrieve each component). Any normal consumer of
the output of the code you posted, one that follows the usual "RGB
stored as 32-bit integer" rules, is going to see a variety of unexpected
results.

For example, if your RGB value is (0, 1, 0), then the output of the
algorithm is 0x000000ff; if that is then decomposed in the usual way
back to an RGB value, by extracting the lowest three bytes from the
32-bit value, red as least-significant-byte, then the resulting RGB
becomes (255, 0, 0). All of the sudden, a color that was practically
black becomes solid, bright red.
I'm sure there are better ways, as Peter said Color.ToArgb() might do
it, but this function was written long before .NET was a twinkle in
anybody's eye!

Age is no insurance against error. ;)

Pete
 
J

Jeff Gaines

For example, if your RGB value is (0, 1, 0), then the output of the
algorithm is 0x000000ff; if that is then decomposed in the usual way back
to an RGB value, by extracting the lowest three bytes from the 32-bit
value, red as least-significant-byte, then the resulting RGB becomes (255,
0, 0). All of the sudden, a color that was practically black becomes
solid, bright red.

It doesn't get decomposed.
It's used for the various functions in cards.dll, I don't think that's
included with Windows any more, I use a copy from a pretty old Windows
install.
I can't find the original notes but it was certainly the standard way of
turning a Color into what cards.dll expected - whatever that was :)
 
P

Peter Duniho

Jeff said:
It doesn't get decomposed.

Unless it's a palette index, it does. And you don't create palette
indices by composing 8-bit RGB values into a single 32-bit int.
It's used for the various functions in cards.dll, I don't think that's
included with Windows any more, I use a copy from a pretty old Windows
install.

cards.dll uses RGB as the color value.

In your first reply, you didn't make clear you were actually using that
value for the cards.dll library. With that additional information, we
can be certain that your code is not correct for the application you
used it for.

As I mentioned before, most of the time the error will be difficult to
notice. But it's there.

Pete
 
J

Jeff Gaines

Unless it's a palette index, it does. And you don't create palette
indices by composing 8-bit RGB values into a single 32-bit int.

I have no idea now what it represents, but it works and it was the
standard way of turning a Color into whatever cards.dll needed.
In your first reply, you didn't make clear you were actually using that
value for the cards.dll library. With that additional information, we can
be certain that your code is not correct for the application you used it
for.

The thread is about the cards.dll library, see the OP!
 
P

Peter Duniho

Jeff said:
I have no idea now what it represents,

As I said, it represents a 24-bit RGB value (the highest byte is unused).
but it works and it was the
standard way of turning a Color into whatever cards.dll needed. [...]

No, it doesn't work. I've already explained why. You can test it
yourself if you don't believe me, using the example I provided.

Pete
 
J

Jeff Gaines

No, it doesn't work. I've already explained why. You can test it
yourself if you don't believe me, using the example I provided.

The advice you give in this group is often very good but you do have a
tendency to slip into the 'I'm right and everybody else is wrong' mode
from time to time.

I've had enough of this discussion, I use the function as posted with the
cards.dll library and it gives the expected results. In my mind that
counts as working so I'm happy with it.
 
P

Peter Duniho

Jeff said:
The advice you give in this group is often very good but you do have a
tendency to slip into the 'I'm right and everybody else is wrong' mode
from time to time.

I don't know what you're talking about. This isn't the kind of question
that is open to debate. The cards.dll has a documented API, as well as
testable behavior.

This isn't about just one person being right and everybody else being
wrong. Quite the contrary: only one person has made an incorrect
statement (you), and I've made only factual, demonstrably correct
statements that are consistent with everyone else's.

Frankly, your attempt to shift the discussion from the technical merits
to a personal attack is a good indicator as to just how confident you
are about your own position. People arguing on the basis of facts don't
have a need to cast aspersions on others. They stick to the facts,
rather than making insults as you've done here.

But, as long as you've raised the question, I'll point out that I don't
have any trouble at all admitting when I've made a mistake, especially
when the correct answer is clearly documented and/or discoverable. I've
done so in the past, and I expect to do so in the future. How about you?
I've had enough of this discussion, I use the function as posted with
the cards.dll library and it gives the expected results. In my mind that
counts as working so I'm happy with it.

Just because you haven't noticed the subtle difference between "correct"
and "almost correct", that doesn't mean your code is correct.

Pete
 
T

Tim Roberts

Jeff Gaines said:
I've had enough of this discussion, I use the function as posted with the
cards.dll library and it gives the expected results. In my mind that
counts as working so I'm happy with it.

Look, your code is CLOSE, and for you it may be WORKABLE, but it's not
right. That, sir, is an indisputable fact. Here is the code you posted:

private int RGBColour(Color colTemp)
{
int intColour = colTemp.B * 255 * 255;
intColour += colTemp.G * 255;
intColour += colTemp.R;
return intColour;
}

Need an example? Try running the color "white" through your code. In
white, R, G, and B are 255. Your code produces the hex result 0xFE01FF.
Does that strike you as the same thing as 0xFFFFFF? That is what "white"
should be, and what it WOULD be if you had used 256 instead of 255 as your
constants.

Try gray, (128,128,128). You should get 0x808080. Instead, you produce
0x7F8080.

You are welcome to stick with it, and for a card-playing application
perhaps you'll never notice, but your code is WRONG.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top