html5 canvas: clipping by color - html

is there any way to choose an area on the canvas by color and clip it?
I want to be able to clip an undefined aread that the only thing in common between all the pixels is that they all have the same color.
thanks

Live Demo
Below is a way to select a color.. and do whatever you want with it. I pass a color I want to find iterate over every pixel and remove the color that matches, since Im not sure what you meant by clipping I assumed you mean remove. However please note on large images this method will be slow.
// Takes an array with 3 color components, rgb
function removeColor(color){
var canvasData = ctx.getImageData(0, 0, 256, 256),
pix = canvasData.data;
for (var i = 0, n = pix.length; i <n; i += 4) {
if(pix[i] === color[0] && pix[i+1] === color[1] && pix[i+2] === color[2]){
pix[i+3] = 0;
}
}
ctx.putImageData(canvasData, 0, 0);
}
removeColor([0,0,255]); // Removes blue.
And like Simon pointed out the code above will get the exact color. Below will grab the approximate color, which is good if you have colors overlapping or very close to each other.
Demo 2 with approximation

Related

reproduce GIF-like image in canvas

I need an image that is drawn in html5 canvas to look like a gif image (make it have 256 colors only). Is there any function that makes canvas have only 256 or less colors and make it convert images that are placed into it have only 256 or less colors?
Thanks in advance
I'm not sure there is such a method in the 2D context of the canvas.
However, it does not seem to be very complicate. 256 colors = 8 levels of red, green and blue.
So you can convert the image to respect this rule.
To achieve this, you need to change the color of each pixels.
Whad I'd do is to create a temporary canvas to manipulate the image, something like this (not tested):
//create copy of the image in a temporary context
this.tmpCanvas = document.createElement('canvas');
this.tmpCanvas.width = myIMage.width;
this.tmpCanvas.height = myIMage.height;
var scaledContext = this.tmpCanvas.getContext('2d');
scaledContext.drawImage(myIMage, 0, 0, myIMage.width, myIMage.height, 0, 0, myIMage.width, myIMage.height);
//get image data
imageData = scaledContext.getImageData(0, 0, myIMage.width, myIMage.height);
//loop over copied image date and modifiy pixels value
for(var i = 0; i < imageData.length; i += 4) { // 4 because RGBA
//red component
imageData[i] = Math.round(imageData[i] / 64);
//green component
imageData[i + 1] = Math.round(imageData[i+1] / 64);
//blue component
imageData[i + 2] = Math.round(imageData[i+2] / 64);
}
scaledContext.putImageData(imageData, 0, 0);
I didn't test this code, but the idea is there

Glow Effect on HTML Canvas, Potentially Using Convolute Kernel / Matrix

I am drawing a PNG image to an HTML canvas and I have implemented a filter system to allow convolute filters to be executed against the image data before it is blitted to the canvas.
Does anyone have an idea how to create a glow effect using either a convolute kernel / matrix (I'm not sure what the terminology is but I'm talking about these: http://www.html5rocks.com/en/tutorials/canvas/imagefilters/) or by other means such as using the globalCompositeOperation (https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html)?
I am aware that you can start with a low opacity and a scaled image then increase opacity while scaling the image down a bit. This works to create a sort-of glow effect but only around the edge of an image.
In an ideal world it would be great to be able to designate areas of the image that have glow using a secondary glow texture. Any ideas on either scenario? :)
Hope the following is along the lines of what you were looking to do, I think it turned out pretty well. So I used the filter library code from the article, and just created a new glow filter for the library, since his code was done pretty well to begin with. Here is a Live Demo showing the glow effect in action.
This is the filter code that you need to add to the library
Filters.glow = function(pixels, passes, image, glowPasses){
for(var i=0; i < passes; i++){
pixels = Filters.convolute(pixels,
[1/9, 1/9, 1/9,
1/9, 1/9, 1/9,
1/9, 1/9, 1/9 ]);
}
var tempCanvas = document.createElement("canvas"),
glowCanvas = document.createElement("canvas"),
tCtx = tempCanvas.getContext("2d"),
gCtx = glowCanvas.getContext("2d");
tempCanvas.width = glowCanvas.width = pixels.width;
tempCanvas.height = tempCanvas.height = pixels.height;
tCtx.putImageData(pixels, 0, 0);
gCtx.drawImage(image, 0, 0);
gCtx.globalCompositeOperation = "lighter";
for(i = 0; i < glowPasses; i++){
gCtx.drawImage(tempCanvas,0,0);
}
return Filters.getPixels(glowCanvas);
}
And this is how you would use the above filter.
var glowImage = document.images[1],
glowMask = document.images[0],
c = document.getElementById("canvas"),
ctx = c.getContext("2d");
window.onload = function() {
var pData = Filters.filterImage(Filters.glow, glowImage, 5, glowMask, 2);
c.width = pData.width;
c.height = pData.height;
ctx.putImageData(pData, 0, 0);
}
You need to provide it with 2 images. The first is the image you want the glow to appear on, and the second is the actual glow mask that is applied to the image. You can then specify how many blur passes to perform, which makes the glow more prominent, and how many glow passes to perform, which add the glow to the image. I use the lighter global composition for the canvas which alpha blends it.
This article is a pretty great resource on creating a glow effect, its also where I got the graphics in order to test my results against theirs.

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.