I tried to convert it into RGB first and then divided the values by 255 but the result is not what I wanted. The colour is brighter than the original.
Have you tried the function valueOf() of the class Color of Libgdx?
Color.valueOf(StringHex);//returns a color from a String hex
The function does the following, as you did not post any code maybe you can spot if something went wrong:
/** Returns a new color from a hex string with the format RRGGBBAA.
* #see #toString() */
public static Color valueOf (String hex) {
hex = hex.charAt(0) == '#' ? hex.substring(1) : hex;
int r = Integer.valueOf(hex.substring(0, 2), 16);
int g = Integer.valueOf(hex.substring(2, 4), 16);
int b = Integer.valueOf(hex.substring(4, 6), 16);
int a = hex.length() != 8 ? 255 : Integer.valueOf(hex.substring(6, 8), 16);
return new Color(r / 255f, g / 255f, b / 255f, a / 255f);
}
Related
I need to XOR two BitmapData objects together.
I'm writing in Haxe, using the flash.* libraries and the AS3 compile target.
I've investigated HxSL and PixelBender, and neither one seems to have a bitwise XOR operator, nor do they have any other bitwise operators that could be used to create XOR (but am I missing something obvious? I'd accept any answer which gives a way to do a bitwise XOR using only the integer/float operators and functions available in HxSL or PixelBlender).
None of the predefined filters or shaders in Flash that I can find seem to be able to do a XOR of two images (but again, am I missing something obvious? Can XOR be done with a combination of other filters).
I can find nothing like a XOR drawmode for drawing things onto other things (but that doesn't mean it doesn't exist! That would work too, if it exists!)
The only way I can find at the moment is a pixel-by-pixel loop over the image, but this takes a couple of seconds per image even on a fast machine, as opposed to filters, which I use for my other image processing operations, which are about a hundred times faster.
Is there any faster method?
Edit:
Playing around with this a bit more I found that removing the conditional and extra Vector access in the loop speeds it up by about 100ms on my machine.
Here's the previous XOR loop:
// Original Vector XOR code:
for (var i: int = 0; i < len; i++) {
// XOR.
result[i] = vec1[i] ^ vec2[i];
if (ignoreAlpha) {
// Force alpha of FF so we can see the result.
result[i] |= 0xFF000000;
}
}
Here is the updated XOR loop for the Vector solution:
if (ignoreAlpha) {
// Force alpha of FF so we can see the result.
alphaMask = 0xFF000000;
}
// Fewer Vector accessors makes it quicker:
for (var i: int = 0; i < len; i++) {
// XOR.
result[i] = alphaMask | (vec1[i] ^ vec2[i]);
}
Answer:
Here are the solutions that I've tested to XOR two images in Flash.
I found that the PixelBender solution is about 6-10 slower than doing it in straight ActionScript.
I don't know if it's because I have a slow algorithm or it's just the limits of trying to fake bitwise operations in PixelBender.
Results:
PixelBender: ~6500ms
BitmapData.getVector(): ~480-500ms
BitmapData.getPixel32(): ~1200ms
BitmapData.getPixels(): ~1200ms
The clear winner is use BitmapData.getVector() and then XOR the two streams of pixel data.
1. PixelBender solution
This is how I implemented the bitwise XOR in PixelBender, based on the formula given on Wikipedia: http://en.wikipedia.org/wiki/Bitwise_operation#Mathematical_equivalents
Here is a Gist of the final PBK: https://gist.github.com/Coridyn/67a0ff75afaa0163f673
On my machine running an XOR on two 3200x1400 images this takes about 6500-6700ms.
I first converted the formula to JavaScript to check that it was correct:
// Do it for each RGBA channel.
// Each channel is assumed to be 8bits.
function XOR(x, y){
var result = 0;
var bitCount = 8; // log2(x) + 1
for (var n = 0; n < bitCount; n++) {
var pow2 = pow(2, n);
var x1 = mod(floor(x / pow2), 2);
var y1 = mod(floor(y / pow2), 2);
var z1 = mod(x1 + y1, 2);
result += pow2 * z1;
}
console.log('XOR(%s, %s) = %s', x, y, result);
console.log('%s ^ %s = %s', x, y, (x ^ y));
return result;
}
// Split out these functions so it's
// easier to convert to PixelBender.
function mod(x, y){
return x % y;
}
function pow(x, y){
return Math.pow(x, y);
}
function floor(x){
return Math.floor(x);
}
Confirm that it's correct:
// Test the manual XOR is correct.
XOR(255, 85); // 170
XOR(170, 85); // 255
XOR(170, 170); // 0
Then I converted the JavaScript to PixelBender by unrolling the loop using a series of macros:
// Bitwise algorithm was adapted from the "mathematical equivalents" formula on Wikipedia:
// http://en.wikipedia.org/wiki/Bitwise_operation#Mathematical_equivalents
// Macro for 2^n (it needs to be done a lot).
#define POW2(n) pow(2.0, n)
// Slight optimisation for the zeroth case - 2^0 = 1 is redundant so remove it.
#define XOR_i_0(x, y) ( mod( mod(floor(x), 2.0) + mod(floor(y), 2.0), 2.0 ) )
// Calculations for a given "iteration".
#define XOR_i(x, y, i) ( POW2(i) * ( mod( mod(floor(x / POW2(i)), 2.0) + mod(floor(y / POW2(i)), 2.0), 2.0 ) ) )
// Flash doesn't support loops.
// Unroll the loop by defining macros that call the next macro in the sequence.
// Adapted from: http://www.simppa.fi/blog/category/pixelbender/
// http://www.simppa.fi/source/LoopMacros2.pbk
#define XOR_0(x, y) XOR_i_0(x, y)
#define XOR_1(x, y) XOR_i(x, y, 1.0) + XOR_0(x, y)
#define XOR_2(x, y) XOR_i(x, y, 2.0) + XOR_1(x, y)
#define XOR_3(x, y) XOR_i(x, y, 3.0) + XOR_2(x, y)
#define XOR_4(x, y) XOR_i(x, y, 4.0) + XOR_3(x, y)
#define XOR_5(x, y) XOR_i(x, y, 5.0) + XOR_4(x, y)
#define XOR_6(x, y) XOR_i(x, y, 6.0) + XOR_5(x, y)
#define XOR_7(x, y) XOR_i(x, y, 7.0) + XOR_6(x, y)
// Entry point for XOR function.
// This will calculate the XOR the current pixels.
#define XOR(x, y) XOR_7(x, y)
// PixelBender uses floats from 0.0 to 1.0 to represent 0 to 255
// but the bitwise operations above work on ints.
// These macros convert between float and int values.
#define FLOAT_TO_INT(x) float(x) * 255.0
#define INT_TO_FLOAT(x) float(x) / 255.0
XOR for each channel of the current pixel in the evaluatePixel function:
void evaluatePixel()
{
// Acquire the pixel values from both images at the current location.
float4 frontPixel = sampleNearest(inputImage, outCoord());
float4 backPixel = sampleNearest(diffImage, outCoord());
// Set up the output variable - RGBA.
pixel4 result = pixel4(0.0, 0.0, 0.0, 1.0);
// XOR each channel.
result.r = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.r), FLOAT_TO_INT(backPixel.r)) );
result.g = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.g), FLOAT_TO_INT(backPixel.g)) );
result.b = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.b), FLOAT_TO_INT(backPixel.b)) );
// Return the result for this pixel.
dst = result;
}
ActionScript Solutions
2. BitmapData.getVector()
I found the fastest solution is to extract a Vector of pixels from the two images and perform the XOR in ActionScript.
For the same two 3200x1400 this takes about 480-500ms.
package diff
{
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.IBitmapDrawable;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
/**
* #author Coridyn
*/
public class BitDiff
{
/**
* Perform a binary diff between two images.
*
* Return the result as a Vector of uints (as used by BitmapData).
*
* #param image1
* #param image2
* #param ignoreAlpha
* #return
*/
public static function diffImages(image1: DisplayObject,
image2: DisplayObject,
ignoreAlpha: Boolean = true): Vector.<uint> {
// For simplicity get the smallest common width and height of the two images
// to perform the XOR.
var w: Number = Math.min(image1.width, image2.width);
var h: Number = Math.min(image1.height, image2.height);
var rect: Rectangle = new Rectangle(0, 0, w, h);
var vec1: Vector.<uint> = BitDiff.getVector(image1, rect);
var vec2: Vector.<uint> = BitDiff.getVector(image2, rect);
var resultVec: Vector.<uint> = BitDiff.diffVectors(vec1, vec2, ignoreAlpha);
return resultVec;
}
/**
* Extract a portion of an image as a Vector of uints.
*
* #param drawable
* #param rect
* #return
*/
public static function getVector(drawable: DisplayObject, rect: Rectangle): Vector.<uint> {
var data: BitmapData = BitDiff.getBitmapData(drawable);
var vec: Vector.<uint> = data.getVector(rect);
data.dispose();
return vec;
}
/**
* Perform a binary diff between two streams of pixel data.
*
* If `ignoreAlpha` is false then will not normalise the
* alpha to make sure the pixels are opaque.
*
* #param vec1
* #param vec2
* #param ignoreAlpha
* #return
*/
public static function diffVectors(vec1: Vector.<uint>,
vec2: Vector.<uint>,
ignoreAlpha: Boolean): Vector.<uint> {
var larger: Vector.<uint> = vec1;
if (vec1.length < vec2.length) {
larger = vec2;
}
var len: Number = Math.min(vec1.length, vec2.length),
result: Vector.<uint> = new Vector.<uint>(len, true);
var alphaMask = 0;
if (ignoreAlpha) {
// Force alpha of FF so we can see the result.
alphaMask = 0xFF000000;
}
// Assume same length.
for (var i: int = 0; i < len; i++) {
// XOR.
result[i] = alphaMask | (vec1[i] ^ vec2[i]);
}
if (vec1.length != vec2.length) {
// Splice the remaining items.
result = result.concat(larger.slice(len));
}
return result;
}
}
}
3. BitmapData.getPixel32()
Your current approach of looping over the BitmapData with BitmapData.getPixel32() gave a similar speed of about 1200ms:
for (var y: int = 0; y < h; y++) {
for (var x: int = 0; x < w; x++) {
sourcePixel = bd1.getPixel32(x, y);
resultPixel = sourcePixel ^ bd2.getPixel(x, y);
result.setPixel32(x, y, resultPixel);
}
}
4. BitmapData.getPixels()
My final test was to try iterating over two ByteArrays of pixel data (very similar to the Vector solution above). This implementation also took about 1200ms:
/**
* Extract a portion of an image as a Vector of uints.
*
* #param drawable
* #param rect
* #return
*/
public static function getByteArray(drawable: DisplayObject, rect: Rectangle): ByteArray {
var data: BitmapData = BitDiff.getBitmapData(drawable);
var pixels: ByteArray = data.getPixels(rect);
data.dispose();
return pixels;
}
/**
* Perform a binary diff between two streams of pixel data.
*
* If `ignoreAlpha` is false then will not normalise the
* alpha to make sure the pixels are opaque.
*
* #param ba1
* #param ba2
* #param ignoreAlpha
* #return
*/
public static function diffByteArrays(ba1: ByteArray,
ba2: ByteArray,
ignoreAlpha: Boolean): ByteArray {
// Reset position to start of array.
ba1.position = 0;
ba2.position = 0;
var larger: ByteArray = ba1;
if (ba1.bytesAvailable < ba2.bytesAvailable) {
larger = ba2;
}
var len: Number = Math.min(ba1.length / 4, ba2.length / 4),
result: ByteArray = new ByteArray();
// Assume same length.
var resultPixel:uint;
for (var i: uint = 0; i < len; i++) {
// XOR.
resultPixel = ba1.readUnsignedInt() ^ ba2.readUnsignedInt();
if (ignoreAlpha) {
// Force alpha of FF so we can see the result.
resultPixel |= 0xFF000000;
}
result.writeUnsignedInt(resultPixel);
}
// Seek back to the start.
result.position = 0;
return result;
}
There are a few possible options depending on what you want to achieve (e.g. is the XOR per channel or is it just any pixel that is non-black?).
There is the BitmapData.compare() method which can give you a lot of information about the two bitmaps. You could BitmapData.threshold() the input data before comparing.
Another option would be to use the draw method with the BlendMode.DIFFERENCE blend mode to draw your two images into the same BitmapData instance. That will show you the difference between the two images (equivalent to the Difference blending mode in Photoshop).
If you need to check if any pixel is non-black then you can try running a BitmapData.threshold first and then draw the result with the difference blend mode as above for the two images.
Are you doing this for image processing or something else like per-pixel hit detection?
To start with I'd have a look at BitmapData and see what is available to play with.
I have to use Foreground Hex color of a Textblock Pragmatically.it does not work.Please help me.
I have tried this example
txtHome.Foreground = new SolidColorBrush(Colors.Red);
but I want use Hex color code not use Color.red etc..
While there are answers that create unnecessary strings, I'd suggest just using the most efficient:
var brush=new SolidColorBrush(Color.FromArgb(0xFF, 0xD0, 0x20, 0x30));
I've just used the FromArgb method to convert the hex representation of a color directly. The first parameter is the alpha or opacity which you can always use 255/0xFF to specify full opacity. Then, it's just providing the 3 bytes representing the color, which are in the same order as they would have appeared in a common hex representation of a color. In the example above: "D02030".
Also, you might consider creating a reusable resource representing the SolidColorBrush and adding it to the app.xaml file so it becomes globally available:
<SolidColorBrush x:Key="myBrush" Color="#D02030" />
Then, in code:
txtHome.Foreground = App.Current.Resources["myBrush"] as SolidColorBrush;
Try this:
public class ColorConverter
{
public static SolidColorBrush GetColorFromHexa(string hexaColor)
{
return new SolidColorBrush(
Color.FromArgb(
Convert.ToByte(hexaColor.Substring(1, 2), 16),
Convert.ToByte(hexaColor.Substring(3, 2), 16),
Convert.ToByte(hexaColor.Substring(5, 2), 16),
Convert.ToByte(hexaColor.Substring(7, 2), 16)
)
);
}
}
Then you can use it like:
txtHome.Foreground = ColorConverter.GetColorFromHexa(("#FFF0F0F0"));
You can use this function to convert hex color in to color value then u can set it on textblock.
public Color ConvertStringToColor(String hex)
{
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 Color.FromArgb(a, r, g, b);
}
Color color1 = ConvertStringToColor("#F0A30A");
txtHome.Foreground = new SolidColorBrush(color1);
txtHome.Foreground = GetColorFromHexa("#FF0000");
SolidColorBrush GetColorFromHexa(string hexaColor)
{
byte r = Convert.ToByte(hexaColor.Substring(1, 2), 16);
byte g = Convert.ToByte(hexaColor.Substring(3, 2), 16);
byte b = Convert.ToByte(hexaColor.Substring(5, 2), 16);
SolidColorBrush soliColorBrush = new SolidColorBrush(Color.FromArgb(0xFF, r, g, b));
return soliColorBrush;
}
Create a method mentioned below,
public SolidColorBrush GetColorFromHexa(string hexaColor)
{
return new SolidColorBrush(
Color.FromArgb(
Convert.ToByte(hexaColor.Substring(1, 2), 16),
Convert.ToByte(hexaColor.Substring(3, 2), 16),
Convert.ToByte(hexaColor.Substring(5, 2), 16),
Convert.ToByte(hexaColor.Substring(7, 2), 16)
)
);
}
and use it as
image.Background = GetColorFromHexa("#FF7b9a30");
Actually, windows phone provide default message box with black background. I am already using custom message box using its toolkit. It has background property but I am unable to assign any value. It gives type casting error.
hope so someone will tell the right value, I alreay tried (0,0,0,0) / "grey" / colors.grey but same error
CustomMessageBox msgbox = new CustomMessageBox()
{
Caption = "Memory Race",
Message ="This is custom message box!",
LeftButtonContent = "OK",
Background = "what?"
};
you can set backgroundcolor
Background = new SolidColorBrush(Colors.Green);
Background property is a color brush.
You must do this:
*.Background = new SolidColorBrush(ConvertStringToColor("#0D0D0E"));
private 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 Color.FromArgb(a, r, g, b);
}
See this link and stylize your CustomMessageBox
I am still working on a actionscript 3 color game. You have an object with a randomly generated color on the right. On the left you have another object and 3 buckets with the RGB colors. The objective is to remix the color of the right object with the 3 buckets and the left object. You carry one of the buckets over the left object. The longer the bucket is over the left object, the more of this offset is added to the object. As you now know, I am working with the red, green, and blueOffset. I now need the buckets to transform the object with CMY and not RGB. I roughly know how to convert RGB value to CMYK, but this doesn't help me when I need to use the RGB offsets to change the color of my object. I know that Actionscript 3 only has the RGB offsets and I dont know how I should solve this problem otherwise.
So my question is: Can you change the color of an movieclip in CMYK or without the ColorTransform? An idea would be very awesome.
English isn't my primary language, so sorry for mistakes...
I don't think you can change the color-offset of an object to CMYK, although you can write a function to convert between RGB and CMYK. On a side note, CMYK is mainly used in printing and it might be better to just stick with RGB. That being said here is how to convert between the two.
RGB to CMYK
The range of each value in RGB is 0 to 255 and the range of each value in CMYK is 0 to 1.
So we need to scale the RGB values so they fall in the 0 to 1 range.
R' = R / 255
G' = G / 255
B' = B / 255
K in CMYK represents the amount of black color and is calculated using R', G' and B'
K = 1 - max(R', G', B')
The other colors are calculated below
C = (1 - R' - K) / (1 - K)
M = (1 - G' - K) / (1 - K)
Y = (1 - B' - K) / (1 - K)
Example class:
import flash.display.MovieClip;
public class ConvertColors extends MovieClip {
public var K:Number = 0.0;
public var C:Number = 0.0;
public var M:Number = 0.0;
public var Y:Number = 0.0;
public function convertToCMYK(R:int, G:int, B:int):void {
var Rprime:Number = R/255;
var Gprime:Number = G/255;
var Bprime:Number = B/255;
this.K = 1 - Math.max( Rprime, Math.max( Gprime, Bprime));
this.C = (1 - Rprime - K)/(1 - K);
this.M = (1 - Gprime - K)/(1 - K);
this.Y = (1 - Bprime - K)/(1 - K);
}
}
CMYK to RGB
RGB ranges from 0 to 255
R = 255 * (1 - C) * (1 - K)
G = 255 * (1 - M) * (1 - K)
B = 255 * (1 - Y) * (1 - K)
Example class:
import flash.display.MovieClip;
public class ConvertColors extends MovieClip {
public var R:int = 0;
public var G:int = 0;
public var B:int = 0;
public function convertToRGB(K:Number, C:Number, M:Number, Y:Number):void {
var Rnum:Number = 0.0;
var Gnum:Number = 0.0;
var Bnum:Number = 0.0;
Rnum = 255 * (1 - C) * (1 - K);
Gnum = 255 * (1 - M) * (1 - K);
Bnum = 255 * (1 - Y) * (1 - K);
this.R = Math.round(Rnum);
this.G = Math.round(Gnum);
this.B = Math.round(Bnum);
}
}
I just found another real solution. If you give the coloroffset a negative value, the color gets transformed into cyan, magenta or yellow! I didn't think that it would be that easy, but it actually is. Now i just need to change my calculation so that it fits to negative stuff. But if you now mix all the buckets, the object gets black! Thats what I wanted and now im happy. The answer with the RGB to CMYK convertion is still very usefull! Thanks a lot.
Say I have the following setup in my AS code:
var color:String = "#0000FF"; //blue
var alpha:Number = 42; //42% or 42/100
How would I combine those into a #RRGGBBAA hex color? I've been Googling around and trying to figure out hexadecimal conversion and notation without luck.
There are two ways you could do this.
One is a bit hacky using int's toString() method and passing 16 as the radix/base:
var rgb:int = (int)("#0000FF".replace("#","0x"));//convert the string to a int (note you can type hex ints starting with 0x (e.g. 0x0000FF)
var a:int = 42;
var rgba:int = int("0x"+rgb.toString(16) + a.toString(16));
or the less hacky and probably faster computationally method using bitwise operators:
var rgb:uint = (uint)("#0000FF".replace("#","0x"));
//extract components using bit shifting (>>) and masking (0xFF)
var r:uint = rgb >> 16 & 0xFF;
var g:uint = rgb >> 8 & 0xFF;
var b:uint = rgb >> 0 & 0xFF;//same as rgb >> 0xFF, just added >> 0 to make the shift obvious
var a:uint = 42;
var rgba:uint = r << 24 | g << 16 | b << 8 | a;
var argb:uint = a << 24 | r << 16 | g << 8 | b;
//test
trace(rgba.toString(16));
trace(argb.toString(16));
Note that using toString(16) in the trace above is to make it useful to us humans,
you'd use the actual uint value when working with hex color values.
Also note that you might want to use ARGB in as3 sometimes, for example when working with BitmapData:
addChild(new BitmapData(100,100,true,0x2a0000ff));//add a 42% transparent blue box (100x100 px)
UPDATE
The above bitshift code snippet actually explains rgb extraction in detail which helps understand things better, but you already have rgb, so it's a matter of adding the alpha component. Also you mentioned 42% which is not the same as on a 0 to 255 scale. Therefore bellow lies your answer:
var rgb:uint = (uint)("#0000FF".replace("#","0x"));
var a:uint = (uint)((42 * .01) * 255);//map 42 from 0<>100 to 0<>255 ( *.01 is the same as / 100 but faster
var rgba:uint = rgb << 8 | a;
var argb:uint = a << 24 | rgb;
Regarding speed, if I run the two different conversion methods a million times here are execution times:
using strings (var rgba:int = int("0x"+rgb.toString(16) + a.toString(16));) takes 851 ms
using bitwise ops (var rgba:uint = rgb << 8| a;) takes 3 ms
As you can the bitwise version is much faster and for your case even less verbose than the string version. Also, now that you understand bitwise operators probably it's easier to read/understand.
In conclusion:
var color:String = "#0000FF"; //blue
var alpha:Number = 42; //42% or 42/100
var rgb:uint = (uint)(color.replace("#","0x"));
var a:uint = (uint)((alpha * .01) * 255);
var rgba:uint = rgb << 8 | a;
trace("hex: #",rgba.toString(16),"test",0x0000ff6b.toString(16));
Also, it's funny you mentioned Google, because you can use the search to convert to hex.
Update:
There seems to be a bit of confusion so I've split the 3 steps into functions:
converting a hex string to an int
converting a alpha percentage (0-100) to a 0-255 int
concatenating the above
Which would be:
function getHex(hexStr:String):uint{
return (uint)(hexStr.replace("#","0x"));
}
function getHexAlpha(alpha:uint):uint{
return (uint)((alpha * .01) * 255);
}
function rgbaConcat(rgb:uint,a:uint):uint{
return rgb << 8 | a;
}
trace("test",rgbaConcat(getHex("#FF9900"),getHexAlpha(50)).toString(16));
or all in one go:
function rgbaConcat(hexStr:String,alpha:uint):uint{
var rgb:uint = (uint)(hexStr.replace("#","0x"));
var a:uint = (uint)((alpha * .01) * 255);
return (rgb << 8 | a);
}
trace("test",rgbaConcat("#123456",100).toString(16));
I'm not sure if sprintf or something similar is available in action script, but you would use something like:
var alpha_2:int = Math.round(255*alpha/100);
var rgba:String = sprintf("%s%2x", color, alpha_2);
By the way, be sure to check whether it is supposed to be #RRGGBBAA or #AARRGGBB
So apparently sprintf is not available, you can use some substitute as mentioned in Is there something like printf in Action Script 3?
If you do not like to use a printf like function you can use:
function hex_char(value:int) {
if (value < 0)
return "X";
if (value < 10)
return String.fromCharCode("0".charCodeAt(0)+value);
if (value < 16)
return String.fromCharCode("A".charCodeAt(0)+value-10);
return "X";
}
var alpha_2:int = Math.round(255*alpha/100);
var rgba:String = color + hex_char(alpha_2/16) + hex_char(alpha_2%16);
alternatively you coulde use the following definition for hex_char which (I assume) will give you an exception/error for any value under 0 or over 15 instead of "X"
function hex_char(value:int) {
return "0123456789ABCDEF".charAt(value);
}