i have a canvas with the following images loaded:
Background Image:
Front Image:
Both together looks like this image:
Now i want to apply a feather effect to the hand boarders to result in to something like this:
I tried the following solution so far. But the result is not like on the above image.
var temp = document.createElement('canvas'),
tx = temp.getContext('2d');
temp.width = scope.canvas.width;
temp.height = scope.canvas.height;
tx.translate(-temp.width, 0);
tx.shadowOffsetX = temp.width;
tx.shadowOffsetY = 0;
tx.shadowColor = '#000';
tx.shadowBlur = 100;
var img = new Image();
img.onload = function() {
tx.drawImage(img, 0, 0, 512, 512);
};
img.src = imageURL; // the hand image
var temp2 = document.createElement('canvas'),
tx2 = temp2.getContext('2d');
temp2.width = scope.canvas.width;
temp2.height = scope.canvas.height;
var img2 = new Image();
img2.onload = function() {
tx2.drawImage(img2, 0, 0, 512, 512);
tx2.save();
tx2.globalCompositeOperation = 'destination-out';
tx2.drawImage(temp, 0, 0);
tx2.restore();
};
img2.src = temp.toDataURL("image/png");
Any idea how to solve this?
Regards
Steve
To feather an image, create a copy of it via a new canvas, create an invers mask of the image with destination-out comp. Then draw the hand again and then mask with destination-ou but with a shadow to create the feather.
var canvas = document.createElement("canvas");
canvas.width = 1024,canvas.height = 1024;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var hand = new Image();
hand .src = "http://i.stack.imgur.com/PbAfc.png";
hand .onload = function(){
var can = document.createElement("canvas");
can.width = this.width;
can.height = this.height;
ct = can.getContext("2d");
// create inverted mask
ct.fillStyle = "black";
ct.fillRect(0,0,this.width,this.height);
ct.globalCompositeOperation = "destination-out";
ct.drawImage(this,0,0);
// create second canvas
var can1 = document.createElement("canvas");
can1.width = this.width;
can1.height = this.height;
ct1 = can1.getContext("2d");
// draw image
ct1.drawImage(this,0,0);
ct1.shadowColor = "black";
ct1.shadowBlur = 30; // amount of feather
ct1.globalCompositeOperation = "destination-out";
ct1.drawImage(can,0,0);
ct1.shadowBlur = 20; // amount of feather
ct1.drawImage(can,0,0); // The mor you draw the greater the FX
ct1.shadowBlur = 10; // amount of feather
ct1.drawImage(can,0,0); // The mor you draw the greater the FX
ct1.globalCompositeOperation = "source-over";
ct.globalCompositeOperation = "source-over";
ctx.drawImage(can1,0,0);
// use the new canvas can1 as the hand image in later code.
}
//ctx.fillStyle = "#e19e9e"
ctx.fillRect(0,0,1024,1024);
Related
I'm trying to draw an existing image onto a canvas and encode it via base64. Here is my code:
var canvas = document.createElement("canvas");
canvas.id = "MyCanvas";
document.getElementById("Table1").appendChild(canvas);
var myCanvas = document.getElementById("MyCanvas");
var myCanvasContext = myCanvas.getContext("2d");
myCanvas.width = 135;
myCanvas.height = 170;
var img = new Image();
img.onload = function(){
myCanvasContext.drawImage(img,0,0);
}
img.src = "https://example.com/asd.png";
var toURL = myCanvas.toDataURL();
console.log(toURL);
It draws the image to the canvas, but the toURL is an empty image base64 code with 135x170 size. I've tried to decode it, but it always shows a blank image.
I can't find what is the problem with it.
The problem is that myCanvas.toDataURL(); is called before the image is actually loaded. For this you'd need to move it inside the onload-callback, like:
var img = new Image();
img.onload = function(){
myCanvasContext.drawImage(img,0,0);
// ...moved here
var toURL = myCanvas.toDataURL();
console.log(toURL);
}
img.src = "https://example.com/asd.png";
The following is a simplified example:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.crossOrigin = "";
img.src = 'https://www.gravatar.com/avatar/8939f42cb6c31e31e570ea8f07fe9757?s=32&d=identicon&r=PG';
img.onload = () => {
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
console.log(canvas.toDataURL());
};
document.body.appendChild(canvas); // append the canvas ...
document.body.appendChild(img); // ... and img for demo purposes only
var canvas = document.createElement("canvas");
canvas.id = "MyCanvas";
document.getElementById("Table1").appendChild(canvas);
var myCanvas = document.getElementById("MyCanvas");
var myCanvasContext = myCanvas.getContext("2d");
myCanvas.width = 500;
myCanvas.height = 500;
var img = new Image();
img.onload = function(){
myCanvasContext.drawImage(img,0,0);
}
img.src = "http://underthebridge.co.uk/wp-content/uploads/2014/03/Example-main-image1.jpg";
var toURL = myCanvas.toDataURL();
console.log(toURL);
var img2 = document.createElement("img");
img2.id = "MyImg";
img2.src = toURL;
document.getElementById("Table1").appendChild(img2);
<div id='Table1'> </div>
You can't put an base64 inside a canvas but only in a tag img.
How to render HTML element and SVG with html2canvas? It's not working.
My code:
$(function() {
window.takeScreenShot = function() {
html2canvas($('#centerpanel'), {
onrendered: function(canvas) {
var svg = document.getElementById("centerpanel");
var serializer = new XMLSerializer();
var ser = serializer.serializeToString(svg);
var context = canvas.getContext('2d');
context.fillStyle = '#8cb4cd';
context.font = '200px sans-serif';
context.globalCompositeOperation = 'lighter';
x = 150;
y = 100;
context.translate(x, y);
context.rotate(-Math.PI / 4.5);
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('123456', 300, 480);
context.restore();
var base64image = canvas.toDataURL("image/png");
console.log(base64image);
var image = new Image();
image.src = base64image;
var w = window.open("");
w.document.write(image.outerHTML + ser);
},
});
}
});
The above code shows both HTML and SVG, but the result is not valid as shown in Figure 1. But I want the results shown in Figure 2.
How do I edit the code to display the desired effect?
Figure 1
Figure 2
I am experiencing an issue with converting a canvas to PNG.
Although the canvas looks exactly as I want it and the conversion from canvas to data URL PNG seems right, the image is blank.
I also tried converting a div to PNG but it did not work for me because I wanted a greyscale filter to be applied. Anyone have any ideas?
JavaScript
var imgis = new Image();
var bubble = new Image();
var canvasWidth;
var canvasHeight;
var ctx = canvas.getContext('2d');
bubble.onload = function() {
var imgis = new Image();
var bubble = new Image();
var ctx = canvas.getContext('2d');
bubble.onload = function() {
// set the canvas' size
canvas.width = this.width;
canvas.height = this.height;
// first fill a rect
ctx.fillStyle = 'rgba(255, 255, 255, 0)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// set the gCO
ctx.globalCompositeOperation = 'luminosity';
// if the browser doesn't support Blend Modes
console.log(ctx.globalCompositeOperation)
if (ctx.globalCompositeOperation !== 'luminosity')
fallback(this);
else {
// draw the image
ctx.drawImage(this, 0, 0);
ctx.drawImage(imgis, 30, 60);
// reset the gCO
ctx.globalCompositeOperation = 'source-over';
}
}
imgis.crossOrigin = "anonymous";
bubble.crossOrigin = "anonymous";
imgis.src = "image1 src";
bubble.src = "image2 src";
function fallback(img) {
// first remove our black rectangle
ctx.clearRect(0, 0, canvas.width, canvas.height);
//draw the image
ctx.drawImage(img, 0, 0);
ctx.drawImage(imgis, 30, 60);
// get the image data
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var d = imgData.data;
// loop through all pixels
// each pixel is decomposed in its 4 rgba values
for (var i = 0; i < d.length; i += 4) {
// get the medium of the 3 first values
var med = (d[i] + d[i + 1] + d[i + 2]) / 3;
// set it to each value
d[i] = d[i + 1] = d[i + 2] = med;
}
// redraw the new computed image
ctx.putImageData(imgData, 0, 0);
}
canvas = document.getElementById('canvas');
var image = Canvas2Image.convertToPNG(canvas);
console.log(image.src);
// document.getElementById('theDemo').src = image.src;
var image_data = $(image).attr('src');
console.log(image_data);
$("#theDemo").attr('src', image_data);
HTML
<canvas id='canvas' > </canvas>
<img src="" id="theDemo" />
I assume you're using canvas2image. You should replace var image = Canvas2Image.convertToPNG(canvas); with Canvas2Image.convertToPNG(canvas, width, height). Hopefully that helps!
EDIT Since the issue is with the actual canvas to base64 conversion, you can try to use the .toDataURL() method instead of using that library. My comment explains how to test this in your specific code.
I am trying to take a pattern and apply it over a png image but only cover the non-transparent part of the image similar to this one.
http://jsfiddle.net/eLmmA/1/
$(function() {
var canvas = document.createElement('canvas');
canvas.width = 250;
canvas.height = 250;
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = 'http://i.stack.imgur.com/QtQrZ.png';
}
img.src = 'http://i.stack.imgur.com/MDGFY.jpg';
document.body.appendChild(canvas);
});
The example above is really close to what I want but I need to be able to use a smaller texture image and repeat it over the none pattern image. I am not familiar with how to use canvas properly but trying to learn more about it.
Thanks in advance!
Never mind I figured it out.
var canvas = document.createElement('canvas');
canvas.width = 250;
canvas.height = 250;
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
var ptrn = canvas_context.createPattern(img, 'repeat');
canvas_context.fillStyle = ptrn;
canvas_context.fillRect(0, 0, canvas.width, canvas.height);
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = $('#base_url').data('base')+'assets/themes/img/download.png';
}
img.src = $('#base_url').data('base')+'assets/uploads/thumbs/1381413411Purple-Night-Owls-thumb.jpg';
$('#itemPreview').html(canvas);
I am using this code to display data of two canvas into third canvas but it is not working.
I am saving the two canvas data using localstorage and passing it to third canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//First canvas data
var img1 = loadImage(localStorage.getItem('cbdata'), main);
//Second canvas data
var img2 = loadImage(localStorage.getItem('cbdata1'), main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if (imagesLoaded == 2) {
// composite now
ctx.drawImage(img1, 0, 0);
ctx.globalAlpha = 0.5;
ctx.drawImage(img2, 0, 0);
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}
Your code works. Check that the content of localStorage.getItem is non-empty. And I also slightly modified display of the images by changing ctx.drawImage commands:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//First canvas data
var img1 = loadImage('http://ep01.epimg.net/elpais/imagenes/2015/10/21/ciencia/1445444934_907402_1445781076_portada_normal.jpg', main);
//Second canvas data
var img2 = loadImage('http://ep01.epimg.net/economia/imagenes/2015/10/22/actualidad/1445508003_507635_1445508894_portada_normal.jpg', main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if (imagesLoaded == 2) {
// composite now
ctx.drawImage(img1, 0, 0, 100, 100);
ctx.globalAlpha = 0.5;
ctx.drawImage(img2, 100, 0, 100, 100);
}
}
function loadImage(src, onload) {
console.log('loadImage', src);
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}
https://jsfiddle.net/4Le4g8ta/