How to convert an Integer to Red, Green, and Blue values - c#

I'm converting an RGB value to a single integer with the following:
public static int RGBtoInt(int red, int greed, int blue)
{
return blue + green + (green * 255) + (red * 65536);
}
but struggling to write an inverse method taking in an integer and returning the single RGB components.
Something of thematic nature with:
public static Vector3 IntToRgb(int value)
{
// calculations...
return new Vector3(red, green, blue);
}
The Color.FromArgb(int) method isn't creating the RGB colour I need.
The RGBtoInt function above matches the RGB integer values returned by OpenGL and I am looking for a reverse method. It's the same conversion method used here.

The conversion can be done as follows.
public static Vector3 IntToRgb(int value)
{
var red = ( value >> 0 ) & 255;
var green = ( value >> 8 ) & 255;
var blue = ( value >> 16 ) & 255;
return new Vector3(red, green, blue);
}
To my understanding, the initial conversion should be done as follows.
public static int RGBtoInt(int r, int g, int b)
{
return ( r << 0 ) | ( g << 8 ) | ( b << 16 );
}

Try this Color c = Color.FromArgb(someInt);
and then use c.R, c.G and c.B for Red, Green and Blue values respectively

Related

C# How to send colorDialog value in 5bitRGB to a textBox?

So I'm creating an editor of a PS2 game. And this game has two "Systems" of colors.
The "normal" RGB R: 0 to 255 G: 0 to 255 B: 0 to 255.
And the or I think it is 5bitRGB R: 0 to 31 G: 0 to 31 B: 0 to 31.
And to make the color change in the game, I have to convert the chosen values in the colorDialog in Hexadecimal for example: R: 255 G: 176 B: 15 In Hexadecimal stands FFB00F.
And then later change these values in the "slots" of 3 bytes via Hex.
Beauty so far so good, but 5bitRGB only have "slots" of 2 bytes.
Example: 5bitRGB R: 31 G: 0 B: 0 in Hex 1F80.
And that's where I do not know what to do, because the colors of the normal RGB I can send the values in Hexadecimal to the textBox.
And then I saved these values textBox in "slots" of 3 bytes via Hex.
Meanwhile the slots for the 5bitRGB color change via Hex They are only "slots" of 2 bytes.
So I would have to send the converted colorDialog value to 5bitRGB for textBox in 2 bytes, is this really possible?
This is a bit of a hack but I think it works ok (may need some refinement).
public static void Main()
{
int red = 0;
int green = 255;
int blue = 0;
//convert to 5-bit values
red = red >> 3;
green = green >> 3;
blue = blue >> 3;
//position them correctly
red = red << 8;
blue = blue << 2;
int greenH = green >> 3;
int greenL = green << 13;
//add the 'always on' bit
int fiveBitRGB = 0x80;
//or them all together
fiveBitRGB = fiveBitRGB | red | blue | greenH | greenL;
fiveBitRGB = fiveBitRGB & 0xffff;
Console.Write("Hex: {0:X4}", fiveBitRGB);
}
Why don't you convert RGB to 5 bit RGB directly in this form?
int _8bitR = _5bitR * 31 / 255;
int _8bitG = _5bitG * 31 / 255;
int _8bitB = _5bitB * 31 / 255;
Because what I understood from your question is that you need these values, and Hexadecimal is not what you want.

How to get System.Windows.Media.Color From From HEX Windows 8 Application

I want to set Border background color from web color value in my windows 8 mobile application .
I found one method that convert hex to Argb but its not working for me ..
private System.Windows.Media.Color FromHex(string hex)
{
string colorcode = hex;
int argb = Int32.Parse(colorcode.Replace("#", ""), System.Globalization.NumberStyles.HexNumber);
return System.Windows.Media.Color.FromArgb((byte)((argb & -16777216) >> 0x18),
(byte)((argb & 0xff0000) >> 0x10),
(byte)((argb & 0xff00) >> 8),
(byte)(argb & 0xff));
}
I am using above method like..
Border borderCell = new Border();
var col = FromHex("#DD4AA3");
var color =new System.Windows.Media.SolidColorBrush(col);
borderCell.Background = color;
But if I pass color hex value like below
var col = FromHex("#FFEEDDCC");
its works fine but it not work on my hex color value.
Before posting this question I go thru this stack answer.
How to get Color from Hexadecimal color code using .NET?
Convert System.Drawing.Color to RGB and Hex Value
Why not simply use System.Windows.Media.ColorConverter?
Color color = (Color)System.Windows.Media.ColorConverter.ConvertFromString("#EA1515");
finally I found one method that return color from hex string
public System.Windows.Media.Color ConvertStringToColor(String hex)
{
//remove the # at the front
hex = hex.Replace("#", "");
byte a = 255;
byte r = 255;
byte g = 255;
byte b = 255;
int start = 0;
//handle ARGB strings (8 characters long)
if (hex.Length == 8)
{
a = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
start = 2;
}
//convert RGB characters to bytes
r = byte.Parse(hex.Substring(start, 2), System.Globalization.NumberStyles.HexNumber);
g = byte.Parse(hex.Substring(start + 2, 2), System.Globalization.NumberStyles.HexNumber);
b = byte.Parse(hex.Substring(start + 4, 2), System.Globalization.NumberStyles.HexNumber);
return System.Windows.Media.Color.FromArgb(a, r, g, b);
}

Generating n number of different solid colors with some distinct variation in 2 colors

The below function have the problem that there is not gurantee of distinguishable difference in the 2 color codes though it will generate distinct solid colors.
private Color[] GenerateNewColor(int count)
{
Color[] colors=new Color[count*2];
for (int i = 0; i < count*2; i++)
{
var values = Guid.NewGuid().ToByteArray().Select(b => (int) b);
int red = values.Take(5).Sum()%255;
int green = values.Skip(5).Take(5).Sum()%255;
int blue = values.Skip(10).Take(5).Sum()%255;
//
colors[i] = Color.FromArgb(255, red, green, blue);
}
HashSet<Color> hashedcolors=new HashSet<Color>(colors);
return hashedcolors.ToArray();
}
Below function will evenly divide the the color codes from #000000 to #ffffff but it does not gurantee of the solid colors. Moreover if the number of colors is less say 5 then it will generate the shade of Black only
private string[] GenerateNewColorByAdding(int count)
{
long hexmin=0X000000;
long hexmax = 0XFFFFFF;
long adder = Convert.ToInt64(hexmax)/count;
string[] s=new string[count];
for (int i = 0; i < count; i++)
{
hexmin = hexmin + adder;
s[i] = String.Format("#{0:X6}" ,hexmin);
}
return s;
}
So I would like to get n number of solid colour's each should be visibility distinct to each other.
Example: if n=50
Requirement 1 : 50 Solid(no transparency) colour's should be generated.
Requirement 2 : each one of them should be visibly distinct to each other like : red,green,blue,orange...etc.,
Note : here 'n' could be maximum 100.
Since there are three independent variables (red, green and blue), you can take the cube root of the number of distinct colours you want, and use that to combine that many values each of red, green and blue to give the required number of colours.
Perhaps something like this would work for you:
public IEnumerable<Color> DistinctColors(int n)
{
int m = (int)Math.Ceiling(Math.Pow(n, 1/3.0));
for (int green = 0; green <= m; ++green)
{
for (int blue = 0; blue <= m; ++blue)
{
for (int red = 0; red <= m; ++red)
{
if (n-- == 0)
yield break;
int r = (int)(0.5 + red*255.0/m);
int g = (int)(0.5 + green*255.0/m);
int b = (int)(0.5 + blue*255.0/m);
yield return Color.FromArgb(r, g, b);
}
}
}
}
[EDIT] Changed the order of RGB generation so that generally more red shades than green shades will be generated (since that seems to give better results).

Converting from RGB ints to Hex

What I have is R:255 G:181 B:178, and I am working in C# (for WP8, to be more specific)
I would like to convert this to a hex number to use as a color (to set the pixel color of a WriteableBitmap). What I am doing is the following:
int hex = (255 << 24) | ((byte)R << 16) | ((byte)G << 8) | ((Byte)B<<0);
But when I do this, I just get blue.
Any ideas what I am doing wrong?
Also, to undo this, to check the RGB values, I am going:
int r = ((byte)(hex >> 16)); // = 0
int g = ((byte)(hex >> 8)); // = 0
int b = ((byte)(hex >> 0)); // = 255
Try the below:
using System.Drawing;
Color myColor = Color.FromArgb(255, 181, 178);
string hex = myColor.R.ToString("X2") + myColor.G.ToString("X2") + myColor.B.ToString("X2");
Using string interpolation, this can be written as:
$"{r:X2}{g:X2}{b:X2}"
You can use a shorter string format to avoid string concatenations.
string.Format("{0:X2}{1:X2}{2:X2}", r, g, b)
You can use ColorHelper library for this:
using ColorHelper;
RGB rgb = new RGB(100, 0, 100);
HEX hex = ColorConverter.RgbToHex(rgb);
Greetings fellow humans,
//Red Value
int integerRedValue = 0;
//Green Value
int integerGreenValue = 0;
//Blue Value
int integerBlueValue = 0;
string hexValue = integerRedValue.ToString("X2") + integerGreenValue.ToString("X2") + integerBlueValue.ToString("X2");

Perform signed arithmetic on numbers defined as bit ranges of unsigned bytes

I have two bytes. I need to turn them into two integers where the first 12 bits make one int and the last 4 make the other. I figure i can && the 2nd byte with 0x0f to get the 4 bits, but I'm not sure how to make that into a byte with the correct sign.
update:
just to clarify I have 2 bytes
byte1 = 0xab
byte2 = 0xcd
and I need to do something like this with it
var value = 0xabc * 10 ^ 0xd;
sorry for the confusion.
thanks for all of the help.
int a = 10;
int a1 = a&0x000F;
int a2 = a&0xFFF0;
try to use this code
For kicks:
public static partial class Levitate
{
public static Tuple<int, int> UnPack(this int value)
{
uint sign = (uint)value & 0x80000000;
int small = ((int)sign >> 28) | (value & 0x0F);
int big = value & 0xFFF0;
return new Tuple<int, int>(small, big);
}
}
int a = 10;
a.UnPack();
Ok, let's try this again knowing what we're shooting for. I tried the following out in VS2008 and it seems to work fine, that is, both outOne and outTwo = -1 at the end. Is that what you're looking for?
byte b1 = 0xff;
byte b2 = 0xff;
ushort total = (ushort)((b1 << 8) + b2);
short outOne = (short)((short)(total & 0xFFF0) >> 4);
sbyte outTwo = (sbyte)((sbyte)((total & 0xF) << 4) >> 4);
Assuming you have the following to bytes:
byte a = 0xab;
byte b = 0xcd;
and consider 0xab the first 8 bits and 0xcd the second 8 bits, or 0xabc the first 12 bits and 0xd the last four bits. Then you can get the these bits as follows;
int x = (a << 4) | (b >> 4); // x == 0x0abc
int y = b & 0x0f; // y == 0x000d
edited to take into account clarification of "signing" rules:
public void unpack( byte[] octets , out int hiNibbles , out int loNibble )
{
if ( octets == null ) throw new ArgumentNullException("octets");
if ( octets.Length != 2 ) throw new ArgumentException("octets") ;
int value = (int) BitConverter.ToInt16( octets , 0 ) ;
// since the value is signed, right shifts sign-extend
hiNibbles = value >> 4 ;
loNibble = ( value << 28 ) >> 28 ;
return ;
}

Categories

Resources