I know how to draw in Angular1 Ionic1.
In my html:
<img ng-src="{{image}}" style="width: 100%">
<canvas id="tempCanvas"></canvas>
In my controller
var startimg="img/face.jpg";
$scope.image=startimg;
var canvas = document.getElementById('tempCanvas');
var context = canvas.getContext('2d');
var source = new Image();
source.src = startimg;
canvas.width = source.width;
canvas.height = source.height;
console.log(canvas);
context.drawImage(source,0,0);
context.font = "100px impact";
textWidth = context.measureText($scope.frase).width;
if (textWidth > canvas.offsetWidth) {
context.font = "40px impact";
}
context.textAlign = 'center';
context.fillStyle = 'white';
context.fillText('HELLO WORLD',canvas.width/2,canvas.height*0.8);
var imgURI = canvas.toDataURL();
$timeout( function(){
$scope.image = imgURI;
}, 200);
This code would definitely draw HELLO WORLD text on the top of face image.
However, in Ionic2/Angular2, it seems doesn't work. I can't even get the document.getElementById('tempCanvas') to work.
Please help.
Thanks.
You can write the following:
#Component({
selector: 'my-app',
template: `<h1>Angular 2 Systemjs start</h1>
<img [src]="image">
<canvas #layout></canvas>
`
})
export class App {
#ViewChild('layout') canvasRef;
image = 'http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo_2013_Google.png';
ngAfterViewInit() {
let canvas = this.canvasRef.nativeElement;
let context = canvas.getContext('2d');
let source = new Image();
source.crossOrigin = 'Anonymous';
source.onload = () => {
canvas.height = source.height;
canvas.width = source.width;
context.drawImage(source, 0, 0);
context.font = "100px impact";
context.textAlign = 'center';
context.fillStyle = 'black';
context.fillText('HELLO WORLD', canvas.width / 2, canvas.height * 0.8);
this.image = canvas.toDataURL();
};
source.src = this.image;
}
}
See also the plunkr https://plnkr.co/edit/qAGyQVqbo3IGSFzC0DcQ?p=preview
Or you can use custom directive like this:
#Directive({
selector: '[draw-text]'
})
class ImageDrawTextDirective {
loaded = false;
#Input() text: String;
#HostListener('load', ['$event.target'])
onLoad(img) {
if(this.loaded) {
return;
}
this.loaded = true;
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.height = img.height;
canvas.width = img.width;
context.drawImage(img, 0, 0);
context.font = "100px impact";
context.textAlign = 'center';
context.fillStyle = 'black';
context.fillText(this.text, canvas.width / 2, canvas.height * 0.8);
img.src = canvas.toDataURL();
}
}
See plunkr for this case https://plnkr.co/edit/BrbAoBlLcbDcx8iDXACv?p=preview
Related
I want to make bot which is changing banner, but this code is not working. Who can help?
if (updateBanner == true) {
var userCount = client.guilds.cache.get('866048794272595999').memberCount;
var canvas = Canvas.createCanvas(960, 540);
var ctx = canvas.getContext('2d');
var Image = Canvas.Image;
var img = new Image();
img.src = 'dm.png';
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.font = '40pt Acrom Light';
ctx.fillText(userCount, 500, 500)
canvas.createPNGStream().pipe(fs.createWriteStream(path.join(__dirname, 'font.png')))
client.guilds.cache.get('866048794272595999').setBanner("font.png");
console.log(`Загрузка изображения`);
updateBanner = false;
} else console.log('Обновление не требуется!');
}, 600000);```
Solved Had to render the images globally outside of the draw method. Here's a link to the github if you find this question and are wondering what the solution looks like in the full code. Its a bit too long to post here as an update. github canvas orbs
back to the original question:
I'm trying to render custom Class objects inside an HTML canvas. Doesn't work with class, but the the same data works without class.
Here's the code:
import './styles/index.css';
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
var window_height = window.innerHeight;
var window_width = window.innerWidth;
canvas.width = 500;
canvas.height = 400;
canvas.style.background = "#232a2e"
const convertSVG = (svgid) => {
const svg = document.getElementById(svgid);
const xml = new XMLSerializer().serializeToString(svg);
const svg64 = btoa(xml);
const b64Start = 'data:image/svg+xml;base64, ';
return b64Start + svg64;
}
class Orb {
constructor(xpos, ypos, radius, speed, image) {
this.xpos = xpos;
this.ypos = ypos;
this.radius = radius;
this.speed = speed;
this.image = convertSVG(image);
}
draw(context) {
const img = new Image();
img.onload = function() {
context.save();
context.beginPath();
context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, (this.xpos - this.radius), (this.ypos - this.radius), 64, 64);
context.restore();
}
img.src = this.image;
}
}
const myOrb = new Orb(150, 150, 30, 1, 'javascript-icon');
myOrb.draw(context);
console.log(myOrb);
const img = new Image();
img.onload = function() {
context.save();
context.beginPath();
context.arc(300, 300, 30, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, (300-32), (300-32), 64, 64);
context.restore();
}
img.src = convertSVG('javascript-icon');
Currently it's only displaying the object I draw explicitly at the bottom of the code, and not the object of class Orb.
Here's a screen cap of the canvas:
current canvas render
EDIT: Additionally, I can generate a class object and draw the orb based on that. Like so:
const myOrb = new Orb(300, 300, 30, 1, 'javascript-icon');
const myOrb2 = new Orb(150, 150, 30, 1, 'java-icon');
const img = new Image();
img.onload = function() {
context.save();
context.beginPath();
context.arc(myOrb.xpos, myOrb.ypos, myOrb.radius, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, (myOrb.xpos-myOrb.radius-2), (myOrb.ypos-myOrb.radius-2), 64, 64);
context.restore();
}
img.src = myOrb.imageSRC;
console.log(myOrb);
console.log(myOrb2);
myOrb2.draw(context);
myOrb renders, but myOrb2 which is drawn with the method of the class is not rendered.
Here's an approach to take. Load the images globally and call draw when image is loaded.
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
var window_height = window.innerHeight;
var window_width = window.innerWidth;
canvas.width = 500;
canvas.height = 400;
canvas.style.background = "#232a2e"
const img1 = new Image();
img1.src = 'https://cdn.iconscout.com/icon/free/png-256/javascript-2752148-2284965.png';
const img2 = new Image();
img2.src = 'https://iconape.com/wp-content/png_logo_vector/cib-javascript.png'
class Orb {
constructor(xpos, ypos, radius, speed, image) {
this.xpos = xpos;
this.ypos = ypos;
this.radius = radius;
this.speed = speed;
this.image = image;
}
draw(context) {
context.save();
context.beginPath();
context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2, false);
context.clip();
context.drawImage(this.image, (this.xpos - this.radius), (this.ypos - this.radius), 64, 64);
context.restore();
}
}
const myOrb = new Orb(150, 150, 30, 1, img1);
const myOrb2 = new Orb(350, 150, 30, 1, img2);
window.onload = function() {
myOrb.draw(context);
myOrb2.draw(context);
}
<canvas id="canvas"></canvas>
I try to copy a certain part of a canvas, then write the copied part in an image. Here is my (wrong) approach:
var c = document.getElementById('MyCanvas'),
ctx = c.getContext('2d');
var ImageData = ctx.getImageData( 25, 25, 150, 150 );
var MyImage = new Image();
MyImage.src = ImageData ; // <-- This is wrong, but I mean something like this
Do you know how can I do it?
Thank you in advance.
ps: I don't want to copy the whole canvas, but a certain part of it.
You could accomplish that in the following way ...
var c = document.getElementById('MyCanvas');
var ctx = c.getContext('2d');
// draw rectangle
ctx.fillRect(0, 0, 200, 200);
ctx.fillStyle = '#07C';
ctx.fillRect(25, 25, 150, 150);
// get image data
var ImageData = ctx.getImageData(25, 25, 150, 150);
// create image element
var MyImage = new Image();
MyImage.src = getImageURL(ImageData, 150, 150);
// append image element to body
document.body.appendChild(MyImage);
function getImageURL(imgData, width, height) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
ctx.putImageData(imgData, 0, 0);
return canvas.toDataURL(); //image URL
}
<canvas id="MyCanvas" width="200" height="200"></canvas>
apology for not giving explanation
Ok let's give that proposal.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id='crop'>Crop Canvas</button>
<hr/>
<canvas id='myCanvas'></canvas>
<hr/>
<script>
(function() {
var can = document.getElementById('myCanvas');
var w = can.width = 400;
var h = can.height = 200;
var ctx = can.getContext('2d');
ctx.font = "30px Arial";
ctx.fillText("Hello World",10,50);
var btn = document.getElementById('crop');
btn.addEventListener('click', function() {
var croppedCan = crop(can, {x: 0, y: 0}, {x: 80, y: 100});
// Create an image for the new canvas.
var image = new Image();
image.src = croppedCan.toDataURL();
// Put the image where you need to.
document.getElementsByTagName('body')[0].appendChild(image);
return image;
});
})();
function crop(can, a, b) {
var ctx = can.getContext('2d');
var imageData = ctx.getImageData(a.x, a.y, b.x, b.y);
var newCan = document.createElement('canvas');
newCan.width = b.x - a.x;
newCan.height = b.y - a.y;
var newCtx = newCan.getContext('2d');
newCtx.putImageData(imageData, 0, 0);
return newCan;
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id='crop'>Crop Canvas</button>
<hr/>
<canvas id='myCanvas'></canvas>
<hr/>
<script>
(function() {
var can = document.getElementById('myCanvas');
var w = can.width = 400;
var h = can.height = 200;
var ctx = can.getContext('2d');
ctx.font = "30px Arial";
ctx.fillText("Hello World",10,50);
var btn = document.getElementById('crop');
btn.addEventListener('click', function() {
var croppedCan = crop(can, {x: 0, y: 0}, {x: 80, y: 100});
// Create an image for the new canvas.
var image = new Image();
image.src = croppedCan.toDataURL();
// Put the image where you need to.
document.getElementsByTagName('body')[0].appendChild(image);
return image;
});
})();
function crop(can, a, b) {
var ctx = can.getContext('2d');
var imageData = ctx.getImageData(a.x, a.y, b.x, b.y);
var newCan = document.createElement('canvas');
newCan.width = b.x - a.x;
newCan.height = b.y - a.y;
var newCtx = newCan.getContext('2d');
newCtx.putImageData(imageData, 0, 0);
return newCan;
}
</script>
</body>
</html>
I have a Javascript function that create a canvas, write a image and a text on it. At the and I need the base64 dataUrl but what I get is only a blank canvas.
This is my function:
function createBreadCrumb(label) {
var canvas = document.createElement('canvas');
canvas.width = 25;
canvas.height = 30;
var img = new Image;
img.src = 'map-pin-breadcrumb.png';
var ctx=canvas.getContext("2d");
img.onload = function(){
ctx.drawImage(img, 0, 0);
ctx.font = "11px Arial";
ctx.textAlign="center";
ctx.fillText(label, 12, 16);
};
return canvas.toDataURL();
}
You are calling toDataURL before the image is loaded. As a result, none of your canvas instructions have run yet. Because the image is loaded asynchronously, you cannot get the resulting canvas synchronously and must use a callback or a promise.
Try this.
function createBreadCrumb(label, callback) {
var canvas = document.createElement('canvas');
canvas.width = 25;
canvas.height = 30;
var img = new Image;
var ctx = canvas.getContext("2d");
img.onload = function(){
ctx.drawImage(img, 0, 0);
ctx.font = "11px Arial";
ctx.textAlign="center";
ctx.fillText(label, 12, 16);
callback(canvas.toDataURL());
};
img.src = 'map-pin-breadcrumb.png';
}
createBreadCrumb("hello", function(crumb){
// do your stuff
});
I have HTML canvas and it work fine to display image.
And I have this jquery code to download the image :
$(".img-download").click(function(){
var data = canvas.toDataURL();
download.href = data; -- I tried this to download image, but PNG file generated cannot be opened in photoshop or any other image manipulation apps
alert (data); -- then, I tried to see what's actually the data content
});
And here's my download button :
Download
Here's what the data content :
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAH0CAYAAAAjYBdQAAAgAElEQVR4XrS9d7Cm6Vnm93Sf0DlMTp0naZSFTCokYNf2er2mbBZvFcG4WGxClQtThVibUpk/EFCLjQoEJmgUkECkrRImLMqiKEmIIIE0EsrSaKIm9/R0DqfP6fb1u677ft9vpJGE7Nqv58w53/e97xPu5w7XHZ7n3fSrv/rblzdt2jzys2lsbKyPy5suD16X9WvT2DyWNm8em/WT1yW+GZs36a/Ll/QXf2/yvZcv5T7uujT9vVnt6WL9LC/pzkvr4+LauXHu7Olx/vxpt7Okpi9d2lB/G2lf/V9W5xuXLo3N+vKy2qNNfjbWL42lpSX/MED6vKzrGIcG6b8Z3yY1TBvctbx5eawzL413WR/Q58rW1bFtxw5dR/uZg+9byn28mPP6+rr/XmIcG/pedPLXvp5xp2/aps/QSWPf2DDdGLPpwk2Mx9MwYUMzN3bZ7fC+vpjm6zXQ55sZtNYia+JWTR/ebFZ7lzZ0v77XSrh9+qflzZtFJ415aWnZffV85vWk+9Dssm7lms36Y/OmpbFrx65x1dXXjOUtq15r+twsuq+vb4wTJ06MCxcujJ07d+hn59gmerImyysr7tN9aU039MPvZfXP2OAvj19jUqPVt9ZoZXXs3rt3bN22bZw4eXI8dfwpX3uJ8XC9aE9/58+fdz9bt24ND7it8FfIDIHCrxsaM/0v+f2SyJI1oM26JRRjLPpv06ZL4r5L4pWN0JzPWWOuh59MUfGxaAOx6MNcU/wCDTOerNNl+vXa5Tro7DH4ojG2bN0ydu/eM5aXV8fpM2fGGf2wjh4jvK8+t4r220STVdOXdjMG5Gvt4vo4d+68aRL+GKKZZoBcqK8lfdY0siyUjCIjfG5R0Yu/aZY2uWZTyb/li2GXPDJmzyuz6elOffsjLhDZ6L9pQbtLy8s1ttzWNDFP0b75V...E/7UDlTn0Y32rlx6914e6lETEZT1eAzDETH/jXAkYXU6L02ljLT72oBMzZVe7rg7CQBwrfnc1/nY0jzZK4FSwx0JSUHuNZzCgpeWQM8PvjVQ3EmNJnEVc6XUBQBYZljS4L4bGWwfa9FAX4ESvPBYLV9B9DwCNVwfSbj0JBIXldRwJPCbZP+Q0XuF9+/5JFH5uzuCPpaaNAr3jxtXSZKFePJTB7rqUh984qb2e2cmY8Hqtt405NBQausnxkk5WvLVHIWjGCguBrwppNrRdcAUkBx0wJEdKlGYTrYRLjkv7gyQZMS4B6muiX++XZZfo21TiRg07PgnPf8O2Ph3gbACRXbJulEtssfjPx0ReNQfjqEob7/fjCweuHg+W5Amf6odvVEXcR4LZN9gqI5CLgmlDubH9nh7FD+tBk4m7JPp1NKUhtSwL8bqCE4MSgJFH7TJ9kfHxqo4GxQ972gI8vdrAvZE4M3+TIa+zpsx9a5qpKlyItM48fwNX6EVSWyGfma4KMIAgu7gbetqG/r4+aNCsS2CQfO7n/CAiWCj835hIfxYyxWN7hq2mr/8ZOOU8WUwxBaEwCPs6vULvn3wkPJDtZBHKpzcOJnFucre2uuHdqaTydPnSvonGs/g0r4OKZXCZuEFidHNk6Y4famEkKDG7BM8fnjcc1UCssWqhwu/CbngZL+OWmBj+/RB2MYTuWXJAcAV0Yz/Kpq8Jqbf3a9hx/HccTt+bYpwFxrp8SrP4mNlgiJE6JtvCdgW+j0c+Hj4zVbNp35SJxMQLO8ZX8pAqRlu6MP+IDLnjfxdlzwU72sEQgG1upWFXA+NlJKuo7b/TGFRtmOEx4nOVDr5jsf4KUNwEnFlihKP/ik+Z4x6PyhI0Cj8pMLlrokRrxi3yh33yjjI/h7lOwjZdqK+cWV8x2fydGz2SwfGVoOUk9X4kbMuan1e6buvh3DB8e0+99vhj89usv/w+6eIb7ytBeBgAAAABJRU5ErkJggg==
why it generate PNG file successfully, but why it can't be opened? why the PNG file is corrupt?
UPDATE : here's my complete jquery script
$(".pepe-thumbnail").click(function(){
var pepe_src = $(this).attr("src");
$("#canvasimg").attr("src", pepe_src);
});
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
var deviceWidth = window.innerWidth;;
canvasWidth = deviceWidth - 40;
canvasHeight = deviceWidth - 40;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
if (canvas.width > 500 || canvas.height > 500){
canvas.width = 560;
canvas.height = 500;
}
var img = document.getElementById("canvasimg");
//imgx = canvas.width/2 - img.width/2;
//imgy = canvas.height/2 - img.height/2;
imgx = 0;
imgy = 0;
function runLoop(){
ctx.lineWidth = 8;
ctx.font = "26pt Lato";
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.lineJoin = "round";
var text1 = document.getElementById("canvastext-top").value;
//text1 = text1.toUpperCase();
var text2 = document.getElementById("canvastext-bottom").value;
//text2 = text2.toUpperCase();
x = canvas.width/2;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, imgx, imgy, canvas.width, canvas.height);
ctx.strokeText(text1, x, 50);
ctx.fillText(text1, x, 50);
ctx.strokeText(text2, x, (canvas.height - 40));
ctx.fillText(text2, x, (canvas.height - 40));
window.setTimeout(runLoop, 14);
};
runLoop();
$(".img-download").click(function(){
var data = canvas.toDataURL();
alert (data);
});
Try this :
$(".img-download").click(function(){
var data = canvas.toDataURL();
$(this).attr("href",data)
$(this).attr("download","imgName.png");
});
Ref:Download canvas image using JS Jquery
var data = canvas.toDataURL();
dataURL = data.replace(/^data:image\/[^;]*/, 'data:application/octet-stream');
dataURL = dataURL.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png');
var aTag = document.createElement('a');
aTag.download = 'download.png';
aTag.href = dataURL;
aTag.click();