i have the canvas in which one image is displaying as it's background and other image is placed in the centre of that image. now i want to save that complete canvas. My recent code is not saving it..
you can see the demo here [ http://jsfiddle.net/himani/gqc9b0qd/3/ ]
var can = document.getElementsByTagName('canvas')[0];
var ctx = can.getContext('2d');
ctx.strokeStyle = '#f00';
ctx.lineWidth = 6;
ctx.lineJoin = 'round';
ctx.strokeRect(40,100,150,100);
var angleInDegrees=0;
var img = document.getElementsByTagName('img')[0];
img.src="http://media1.santabanta.com/full1/Miscellaneous/Cartoon%20Characters/cartoon-characters-47a.jpg";
ctx.drawImage(img,40,100,150,100);
function drawRotated(degrees){
ctx.clearRect(0,0,300,300);
ctx.save();
ctx.translate(40+150/2,100+100/2);
ctx.rotate(degrees*Math.PI/180);
ctx.strokeRect(-150/2,-100/2,150,100);
ctx.drawImage(img,-150/2,-100/2,150,100);
ctx.restore();
}
$("#clockwise").click(function(){
angleInDegrees+=30;
drawRotated(angleInDegrees);
});
$("#save").click(function(){
var ua = window.navigator.userAgent;
if (ua.indexOf("Chrome") > 0) {
// save image without file type
var canvas = document.getElementsByTagName('canvas')[0];
document.location.href = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
// save image as png
var link = document.createElement('a');
link.download = "test1.png";
link.href = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");;
link.click();
}
else {
alert("Please use Chrome");
}
});
If you want to export with toDataUrl an image from a cross origin request, try define the crossOrigin attribute on your image.
var img = document.getElementsByTagName('img')[0];
img.crossOrigin = "anonymous";
img.src="http://media1.santabanta.com/full1/Miscellaneous/Cartoon%20Characters/cartoon-characters-47a.jpg";
img.onload = function () {
ctx.drawImage(img,40,100,150,100);
};
It worked just fine for me. Fore more information about this attributes and the availables values, take a look at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes
Related
This question already has answers here:
Callback/scope understanding
(3 answers)
Closed 1 year ago.
I am having trouble drawing an image with CSS filters onto a canvas. I want to apply the CSS filters with sliders/range inputs that I have. The image that the filters will be applied to is an image that you upload from your files. This image is put into a variable in a function I have that will upload the image. The function for the slider is separate, and therefore I can't apply the filters and draw the image again in the function that is activated when the sliders are being dragged.
I need it to be drawn instead of just putting the filters on the canvas itself so that I can download the image with filters.
Here is the javascript code:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var img = new Image();
img.onload = function() {
var ratio = this.height / this.width;
canvas.height = canvas.width * ratio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var container = document.getElementById("container")
var download = document.getElementById("download")
var adjustments = document.getElementById("adjustments")
download.addEventListener("click", function() {
var link = document.createElement('a');
link.download = 'filename.png';
link.href = canvas.toDataURL();
link.click();
});
var prop1 = document.getElementById("prop1");
var open = true;
adjustments.addEventListener("click", function() {
if (open === true) {
prop1.style = "margin-left: -240px;";
adjustments.classList.remove("line");
open = false;
} else if (open === false) {
prop1.style = "margin-left: 50px;";
adjustments.classList.add("line");
open = true;
}
});
var contrast = document.getElementById("contrast");
var brightness = document.getElementById("brightness");
var slider1 = contrast.value;
var slider2 = brightness.value;
function effect() {
slider1 = contrast.value;
slider2 = brightness.value;
ctx.filter = "contrast(" + slider1 + ") brightness(" + slider2 + ")";
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
contrast.oninput = function() {
effect()
};
brightness.oninput = function() {
effect()
};
You could try clearing the canvas with ctx.clearRect() then redraw everything on the canvas. I'd also recommend creating a function to redraw the items just for easier reading.
I want to fill my canvas with a image (base64-string) and than add a text into the canvas.
Initial idea (javascript browser application): I want to set the base64-string txtb64 (Image) as background image of the canvas and than add the text over it.
downloadtext: function() {
var sign = this.getView().byId("SigId");
var txtb64 = signpad.getSignAsJpeg();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var image = new Image();
image.src = txtb64;
image.addEventListener("load", function(event) {
console.log("Ready!");
});
ctx.drawImage(image, 0, 0);
ctx.fillText('My random text', 0, 0);
var dataURL = canvas.toDataURL("image/jpeg");
var image = new Image();
var element = document.createElement('a');
image.src = dataURL;
element.setAttribute('href', image.src);
element.setAttribute('download', 'image');
element.style.display = 'none';
element.click();
},
The problem is I always get a black rectangle as output.
What is wrong with my code, because i can see no error.
It looks like you should put the code needed to download the new image inside the "load" event handler of the image you create. This is needed because the load event could trigger after the code beneath it runs, resulting in an empty image being put onto the canvas.
Also you declare var image = new Image(); twice, which could also be causing issues. Calling one image1 and the other image2 will prevent that.
WARNING Running this snippet triggers a download request.
var data = "data:image/png;base64,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";
var can = document.getElementById('can');
var ctx = can.getContext('2d');
var img = new Image();
img.src = data;
img.addEventListener('load', e =>
{
ctx.drawImage(img, 0, 0);
ctx.fillText('My random text', 100, 100);
var dataURL = can.toDataURL("image/jpeg");
var image = new Image();
var element = document.createElement('a');
image.src = dataURL;
element.setAttribute('href', image.src);
element.setAttribute('download', 'image');
document.body.appendChild(element);
element.click();
});
<canvas width="300" height="300" id="can"></canvas>
I've made a Chrome Extension that:
Takes a screenshot of a website, opens anew window, cuts the image using canvas, and downloads the image. Now I want to display the image so I create an image and set its path to file:///C:/Users/myuser/Downloads/myfile.png.
But the image doesn't show up. I tried removing the "file" or setting a timeout but nothing works, however when I click the image link in the dev console it takes me to the picture and it works.
Here's the code from ´background.js´:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.captureVisibleTab(null, {}, function(image){
var x = window.open();
var cv = x.document.createElement('canvas');
x.document.body.appendChild(cv);
var canvas = x.document.querySelector('canvas');
canvas.width = 928
canvas.height = 490;
var img = new Image();
var code = new Date().getTime();
img.onload = function(){
ctx.drawImage(this, 315, 138, 928, 490, 0, 0, 928, 490);
var toCopy = canvas.toDataURL("image/png");
var link = x.document.createElement('a');
link.download = code + '.png';
link.href = toCopy;
link.click();
setTimeout(function(){
var el = new Image();
el.src = 'file:///C:/Users/myuser/Downloads/'+code+'.png';
x.document.body.appendChild(el);
x.console.log(x.location);
}, 2000);
canvas.parentElement.removeChild(canvas);
}
img.src = image;
var ctx = canvas.getContext('2d');
});
});
Requirement:
Users can type in text that goes as an overlay on top of an image.
Users can download the image with the overlay.
To do this, I'm drawing the image onto the canvas, filling with the text and then setting the link's href to the canvas's dataURL.
Findings:
I can see the text overlay on the image in the canvas just fine.
If I right-click on the canvas and download the image, I can see the text overlay just fine.
If I click on the link, I see the original image without the text overlay.
What did I miss?
Here's the snippet:
var imgURL = 'https://upload.wikimedia.org/wikipedia/commons/5/56/Neptune_Full.jpg';
function loadCanvas(dataURL) {
var canGreeting = document.getElementById('canGreeting');
var context = canGreeting.getContext('2d');
// load image from data url
var imageObj = new Image();
imageObj.crossOrigin = 'anonymous';
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
context.font = "20px sans-serif";
context.fillStyle = "#FFFFFF";
var arrayOfLines = $('#txtGreetingText').val().split('\n');
var y = 50;
var i = 0;
$(arrayOfLines).each(function() {
context.fillText(arrayOfLines[i], 50, y);
i++;
y += 30;
});
};
imageObj.src = dataURL;
lnkDownload.download = "card.jpg";
lnkDownload.href = imageObj.src;
}
$(document).ready(function() {
loadCanvas(imgURL);
$("#txtGreetingText").on("keydown", function(e) {
loadCanvas(imgURL);
});
});
textarea {
width: 420px;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<textarea name="txtGreetingText" id="txtGreetingText"></textarea>
<br/>
<canvas id="canGreeting" width="480" height="480"></canvas>
<br/>
<a id="lnkDownload">Download this card</a>
href attribute should be pointing to base64 encoded image of the canvas source. Do this:
$(arrayOfLines).each(function() {
context.fillText(arrayOfLines[i], 50, y);
i++;
y += 30;
});
// udpate link to image
// Grab base64 encoded URL
var url = canGreeting.toDataURL("image/png;base64;");
lnkDownload.href = url;
I'm attempting to pull an image (in this case, /camera/frame, which is a known-good JPG), and load it as the background of my document.body.
Here's my code thus far:
var backgroundImage = new Image();
backgroundImage.onload = function ()
{
console.log("onload");
document.body.style.backgroundImage = this.src;
};
backgroundImage.src = 'camera/frame';
"onload" prints as expected, and this.src prints out the full URL to /camera/frame, however document.body.style.backgroundImage remains "".
I believe you may be missing two things.
var path = 'path/to/image.jpg';
document.body.style.background='url('+path+')';
Canvas 2D to the rescue!
var backgroundImage = new Image();
backgroundImage.onload = function ()
{
var canvas = document.getElementById('canvas');
canvas.width = this.width;
canvas.height = this.height;
var canvasContext = canvas.getContext('2d');
canvasContext.drawImage(this, 0, 0, this.width, this.height);
};
backgroundImage.src = 'camera/frame';
backgroundImage.width = $(window).width();
backgroundImage.height = $(window).height();
Loads the image in the background, then draws it into the canvas seamlessly!