Color based on distance - actionscript-3

This question already has a working answer at : Weird graphical bug in > AS3?
I'm trying to make a simple tile lighting system in AS3 and the problem I've come across is that I have no idea how to change the color based on distance using hexadecimal color codes
heres the code for the color changing part:
for (var i:int = 0; i < buttons.length; i++) {
lightFact = getDistance(lightSource, buttons[i])
colorTransform2.color = 0x000000
DisplayObject(buttons[i]).transform.colorTransform = colorTransform2;
}
lightFact being the distance from the lightSource, if you can't figure that out from the function name.

I'm not sure what the final objective is for this code but here we go.
getDistance() should return a numeric value. Next step is to create a function or algorithm that codify a number into a color. This could be just setting the R of the RGB color equals to the distance (setting a cap in 255) or many if-else statements like:
if(lightFact < XValue)
{
colorTransform2.color = 0xFF0000;
}
else if(lightFact < YValue)
{
colorTransform2.color = 0x00FF00;
}
else
{
colorTransform2.color = 0x0000FF;
}
or any other more complex codification you might like. Any codification you choose will, either way, need some kind of logic that checks lightFact's value and based on it (and any other variables you may have) makes a calculation or decision to set a different value to colorTransform2.color. Otherwise colorTransform.color will always be 0x000000 (black/turned off).

Related

Using byteArray with getPixel (no 's') then setPixelS

Here is what I am trying to do:
one byteArray (colorsByteArray) holds color values, that I created with the "getPixels" method;
for every pixel on screen, I make calculations and depending on that I get a rank that I use to retrieve the proper color value inside colorsByteArray;
finally, I write inside a second byteArray (pixelsByteArray) the color I just retrieved. Then I 'draw' this byteArray using the "setPixels" method.
Problem is I do not find the same image as if I simply wrote a "setPixel" for every pixel in my loop. The image I get is missing one line out of two, and is kind of repeated three times horizontally. Of course I guess I must be writing (or reading) something wrong from my second byteArray, but can someone explain me what I am doing wrong? Or even if my efforts are worth anything actually :-) cause I didn't find anything quite like this so far...
Thanks!
Here is a bit of my code to make things clearer:
colorsByteArray = bitmDext.getPixels(new Rectangle(0, 0, myShadeBMD.width, 1));
canvas.lock();
for(var i:int = 0; i < STAGE_WIDTH; i++)
{
for(var j:int = 0; j < STAGE_HEIGHT; j++)
{
//make some calculation on each pixel to get the 'colorRank' uint value
colorsByteArray.position = colorRank * 4;//unsigned int is 32 bytes, representing 4 slots of a byteArray
var colorValue:uint = colorsByteArray.readUnsignedInt();
//canvas.setPixel(i, j, colorValue);//works just fine
pixelsByteArray.writeUnsignedInt(colorValue);
}
}
pixelsByteArray.position = 0;
var myRect:Rectangle = new Rectangle(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
canvas.setPixels(myRect, pixelsByteArray);
canvas.unlock();
added a picture that may help:
http://www.oghel.com/pictures/stackOverflow/example3
the expected part is on the right, the wrong one on the left.

Replace the selected pixel

How do I replace the selected pixel of the image? I used set pixel and get pixel concept but not getting the desired effect.
http://www.digital-photography-school.com/wp-content/uploads/2009/07/before-after.jpg
var s_color = 0x0083C7;
color_picker.addEventListener(ColorPickerEvent.CHANGE, changeColor);
function changeColor(ColorPickerEvent)
{
var _color = color_picker.selectedColor.toString(16);
var color = String("0x"+_color);
for (var j = 0; j <m_inputImage.width; j++)
{
for (var k = 0; k < m_inputImage.height; k++)
{
if (m_inputImage.getPixel(j,k)== s_color)
{
m_inputImage.setPixel(j,k,color);
}
}
}
s_color = color;
}
I want similar type effect.
Please guide me.
This is not a job for BitmapData, you should use Pixelbender for this.
http://www.adobe.com/devnet/flash/articles/pixel_bender_basics.html
You can find all shaders here, there are a lot of hue/saturation and color manipulation filters so pick one that suits you the best.
http://www.adobe.com/cfusion/exchange/index.cfm?event=productHome&exc=26&loc=en_us
I would use Photoshop instead of Flash to achieve the effect you desire.
However Photoshop is kind of expensive, so I would use the Bitmap class in conjunction with the BitmapData class and use an algorithm to run through each pixel and check for a certain threshold of red and convert it to the right threshold of yellow. If you would post the code you already have written I could possibly add to it, I'm not going to spend the next hour writing an example though.

Actionscript object colour change / tint

i am new to Actionscript and I need help changing the colour of an object which is called with add child, i need the colour to change once the user has selected the desired colour they want from a combo box:
//MY CODE
if (e.target.value == "blue")
{
//need to change to this (0x0000FF)
//enter code here
}
Any help much appreciated!
Try using the color transform object.
var redAmount:Number = 0;
var greenAmount:Number = 0;
var blueAmount:Number = 1;
var alphaAmount:Number = 1;
var redOffset:Number = 0;
var greenOffset:Number = 0;
var blueOffset:Number = 0;
var alphaOffset:Number = 0;
yourDisplayObject.transform.colorTransform = new ColorTransform(redAmount, greenAmount, blueAmount, alphaAmount, redOffset, greeenOffset, blueOffset, alphaOffset);
The first four variables are multipliers - they will take the existing color value and adjust it as if multiplying by that number. So to reduce a color by 1/2 use 0.5. To make black set all to 0. To change nothing make all 1's.
The second four variables will increase or decrease the color amount of all pixels by that amount. So to make a color hit a specific hex value, say 0xFFCC33, you would do this:
yourDisplayObject.transform.colorTransform = new ColorTransform(0, 0, 0, 1, 0xFF, 0xCC, 0x33, 0x00);
Here is a link to the adobe documentation if you need more help:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/ColorTransform.html
If you decide you want to change the color gradually instead of instantly take a look at TweenMax from greensock. The greensock tween classes are a widely used workhorse of actionscript programming.
To tint a display object with TweenMax the code would be:
TweenMax.to(yourDisplayObject, 1, {tint:0x0000FF});
This class applies a color transform to the object using that code, but it changes the values gradually over time
Here is a link to where you can get TweenMax.
http://www.greensock.com/tweenmax/
Here is the easiest to understand (as I see it anyway) way to accomplish this:
if (e.target.value == "blue")
{
var colorTransform:ColorTransform = yourObject.transform.colorTransform; //store the current color data for the object
colorTransform.color = 0x0000FF; //make it totally blue
yourObject.transform.colorTransform = colorTransform; //now assign it back to the object
}

What does the mask parameter do in the threshold method of the BitmapData class?

I'm trying to replace a color and colors near it in a bitmap.
threshold() seems to work but it seems to be that you have to specify the exact color "==" or all colors before or after the exact color "<" & ">" plus "<=" and ">=". I am hoping that the mask parameter will help me find a way to find a color and a dynamic range of colors before and after it to be replaced. What is its intended usage?
Per the comment below Example 1 and 2:
bit.threshold(bit, bit.rect, point, ">", 0xff000000, 0xffff0000, 0x00FF0000);
bit.threshold(bit, bit.rect, point, ">", 0xff000000, 0xffff0000, 0x00EE0000);
If you're trying to do a flood fill, I don't think the mask parameter will help you. The mask parameter lets you ignore parts of the color in the test. In your case, you want to take into account all the channels of the color, you just want the matching to be fuzzy.
e.g. If you want to replace all pixels where the red component is 0, you can set mask to 0x00FF0000, so it will ignore the other channels.
The implementation pseudo-code probably looks something like this:
input = readPixel()
value = input & mask
if(value operation threshold)
{
writePixel(color)
}
Neither of your samples will produce anything because the mask limits the values to be between 0x00000000 and 0x00FF0000, then tests if they're greater than 0xFF000000.
I have also done this and eventually, I have found it best to create my own threshold-method. You can find it below. Everything is explained in comment.
//_snapshot is a bitmapData-object
for(var i:int = 0; i <= _snapshot.width; i++)
{
for(var j:int = 0; j <= _snapshot.height; j++)
{
//We get the color of the current pixel.
var _color:uint = _snapshot.getPixel(i, j);
//If the color of the selected pixel is between certain values set by the user,
//set the filtered pixel data to green.
//Threshold is a number (can be quite high, up to 50000) to look for adjacent colors in the colorspace.
//_colorToCompare is the color you want to look for.
if((_colorToCompare - (100 * _threshold)) <= _color && _color <= (_colorToCompare + (100 * _threshold)))
{
//This sets the pixel value.
_snapshot.setPixel(i, j, 0x00ff00);
}
else
{
//If the pixel color is not within the desired range, set it's value to black.
_snapshot.setPixel(i, j, 0x000000);
}
}
}

Bitmap conversion - Creating a transparent + black image from a B&W source

I have a whole bunch of jpg files that I need to use in a project, that for one reason or another cannot be altered. Each file is similar (handwriting), black pen on white BG. However I need to use these assets against a non-white background in my flash project, so I'm trying to do some client-side processing to get rid of the backgrounds using getPixel and setPixel32.
The code I am currently using currently uses a linear comparison, and while it works, the results are less than expected, as the shades of grey are getting lost in the mix. Moreso than just tweaking my parameters to get things looking proper, I get the feeling that my method for computing the RGBa value is weak.
Can anyone recommend a better solution than what I'm using below? Much appreciated!
private function transparify(data:BitmapData) : Bitmap {
// Create a new BitmapData with transparency to return
var newData:BitmapData = new BitmapData(data.width, data.height, true);
var orig_color:uint;
var alpha:Number;
var percent:Number;
// Iterate through each pixel using nested for loop
for(var x:int = 0; x < data.width; x++){
for (var y:int = 0; y < data.height; y++){
orig_color = data.getPixel(x,y);
// percent is the opacity percentage, white should be 0,
// black would be 1, greys somewhere in the middle
percent = (0xFFFFFF - orig_color)/0xFFFFFF;
// To get the alpha value, I multiply 256 possible values by
// my percentage, which gets multiplied by 0xFFFFFF to fit in the right
// value for the alpha channel
alpha = Math.round(( percent )*256)*0xFFFFFF;
// Adding the alpha value to the original color should give me the same
// color with an alpha channel added
var newCol = orig_color+alpha;
newData.setPixel32(x,y,newCol);
}
}
var newImg:Bitmap = new Bitmap(newData);
return newImg;
}
Since it's a white background, blendMode may give you a better result.