I am creating a vector of spriteframes but I don't know how to set the opacity of the background of said frames. Here's my code:
for (int i = 1; i <= 2; i++)
{
sprintf(str, "idle%i.png", i);
auto frame = SpriteFrame::create(str, Rect(0, 0, 26, 32));
idleFrames.pushBack(frame);
}
auto idleAnimation = Animation::createWithSpriteFrames(idleFrames, 0.20f);
idlingAnim = Animate::create(idleAnimation);
idlingAnim->retain();
this->runAction(RepeatForever::create(idlingAnim));
I'm new at cocos2d and I don't know if this is exactly the right way to do it. Can anyone tell me how to set the background opacity of the frames?
This is what happens at the moment: https://i.imgur.com/tdkk0zN.png
Use any Image editor such as GIMP, Photoshop to edit the image. Cocos change entire the image's opacity, not only background. (You may achieve that by coding shaders but it is very hard).
Related
I've searching a way to fill an image surface with a color with canvas but didn't find what i'm looking for.
Is there actually any way to do it?
There is an example of what i'm talking about:
If the image is like this:
I would need to paint this with canvas:
Just fill the actual image surface with a color (black in this case).
I think this Android method does the same, so I hope there is something similar on canvas.
imageView.setColorFilter(Color.RED);
Thank you in advance.
You can use composition mode to do this, more specifically the source-in:
ctx.globalCompositeOperation = "source-in";
ctx.fillRect(x, y, w, h); // fill the image area using current color
// Using the original colored logo in OPs post:
var img = new Image; img.onload = go; img.src = "//i.stack.imgur.com/kv435.png";
function go() {
var ctx = c.getContext("2d");
c.width = this.width; c.height = this.height;
ctx.drawImage(this, 0, 0);
// change color
ctx.globalCompositeOperation = "source-in";
ctx.fillRect(0, 0, c.width, c.height); // def. color is black
}
<canvas id=c></canvas>
What's important to be aware of though is that composite operations works with the alpha channel. If the image doesn't have an alpha channel but just a white background, this approach won't work. In that case you would need to iterate over each pixel and replace all non-white pixels to the target color pixel.
For this approach you can use getImageData(). But my recommendation is to prepare the image so it has an alpha channel embedded before processing.
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.
I have two images, one of which is a small icon that is superimposed over the first image. My icon has a white background, so when the icon is placed over the other image, we get this effect where a white square appears over the image. Ideally, I do not want to display this white background on top of my other image. Is there is a CSS property I can apply to my icon to make its white background transparent?
Actually there is a way although only currently supported on Chrome, Firefox, and Safari. If the background color is white, you can add the CSS property:
mix-blend-mode: multiply;
You can read more about it here: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
Opacitator
mix-blend-mode does work for some browsers, but we've found that it causes performance issues in chrome, I have no idea why.
A designer on my team came up with this genius hack, where you create a layer that is mostly transparent, but when it is laid over a white background, it's color will match the color of the surrounding background.
The way this "magical" color is found; is by calculating how much darker each color axis should be for the amount of opacity removed. The formula for this is 255 - ( 255 - x ) / opacity. The issue is: If the opacity is set too low the formula gives you negative numbers (which can't be used). If the opacity is too high, you'll get some coloring on the non-white portions of your image.
Initially we used a spreadsheet that would do the calculations and through manual trial and error we would find that Goldilox color.
Once we started using sass I realized that this can be accomplished with a binary search. So I created a sass function that does the work for us.
Check out this gist on sassmeister. Pass your background color in-to the opacitator function on line 56 of the sass-code. and use the generated rgba color in a div (or a pseudo element) to overlay the image.
I also created a working example on codepen.
As there is no reliable way to remove background with CSS, sharing a code snippet of how I did it with JS:
public async removeImageBackground(image) {
const backgroundColor = { red: 255, green: 255, blue: 255 };
const threshold = 10;
const imageElement = new Image();
imageElement.src = image;
await new Promise(function(resolve) { imageElement.addEventListener('load', resolve); });
var canvas = document.createElement('canvas');
canvas.width = imageElement.naturalWidth;
canvas.height = imageElement.naturalHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(imageElement, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (var i = 0; i < imageData.data.length; i += 4) {
const red = imageData.data[i];
const green = imageData.data[i + 1];
const blue = imageData.data[i + 2];
if (Math.abs(red - backgroundColor.red) < threshold &&
Math.abs(green - backgroundColor.green) < threshold &&
Math.abs(blue - backgroundColor.blue) < threshold) {
imageData.data[i + 3] = 0;
}
}
ctx.putImageData(imageData, 0, 0);
return canvas.toDataURL(`image/png`);
}
You can make a container for your image.
Then for the css of the container:
overflow:hidden; height: (depends on your image, then make it a smaller px); width:100%;
Hope it helps. :)
No. Not yet...
It is getting very close to possible, though. Check out this article about CSS Filters, an experiemental css feature, that is doing some things client-side that are neat.
CSS Filters
I have about 10 images I draw on canvas in html5. Then, I would like to move the first image only, the other one should remain in place. here is the code :
ctx.clearRect(0, 0, 500, 375);
ctx.translate(20, 0);
I understand that I move the whole canvas with that code... but how to move only one image not the whole canvas... I think about using two canvas... but look like a bad solution to me !...
i guest the save and restore will be used, but when i try, it repeat the images... not good !. i am kind of lost, and read a lot of tutorial and read that : Canvas - move image-problem but not usefull. HELP
Here is my final working code
function drawOnCanvas() {
ctx.save();
ctx.clearRect(0, 0, 500, 375);
ctx.globalAlpha = 1;
ctx.translate(image_objects[0].width/2, image_objects[0].height/2);
ctx.scale(scale,scale);
ctx.translate(-image_objects[0].width/2, -image_objects[0].height/2);
ctx.translate(image_objects[0].width/2, image_objects[0].height/2);
ctx.rotate(rotate);
ctx.translate(-image_objects[0].width/2, -image_objects[0].height/2);
ctx.translate(movex, movey);
ctx.drawImage(image_objects[0],0,0);
ctx.restore();
if (hide_images == false) {
for (var i = 1; i < image_objects.length; ++i) {
ctx.globalAlpha = opacity;
ctx.drawImage(image_objects[i], 0, 0);
}
}
}
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