Save multiple images in canvas JQuery - javascript

Can we save the image in canvas. Like as shown in the JSFiddle.
I want to save the image in such a way the balloon should come over the image
$(document).ready(function() {
var d_canvas = document.getElementById('canvas');
var context = d_canvas.getContext('2d');
var background = document.getElementById('background');
var ballon = document.getElementById('ballon')
context.drawImage(background, 0, 0);
$('#ballon').draggable();
$('#draw').click(function() {
var $ballon = $('#ballon'),
$canvas = $('#canvas');
var ballon_x = $ballon.offset().left - $canvas.offset().left,
ballon_y = $ballon.offset().top - $canvas.offset().top;
context.drawImage(ballon, ballon_x, ballon_y);
$ballon.hide();
$(this).attr('disabled', 'disabled');
});
});

There are generally two ways to get an image from a canvas:
using getImageData() to get the rgba value for every pixel for a given rectangle of the canvas.
using toDataURL() to get a Base64 string of the entire canvas.
The second method is probably most useful, and combined with some HTML5 magic, and the download attribute, we can create a downloadable image or send the string to the server and save it as an image :
var base64 = d_canvas.toDataURL("image/png");
var a = document.createElement('a');
a.href = base64,
a.target = '_blank';
a.download = 'myImage.png';
document.body.appendChild(a);
a.click();
If you need the baloon to be in a specific place, moving that should be trivial.
Here's a
FIDDLE
Note that I had to remove the external images and use base64 to avoid cross-origin images in the canvas.

Related

downloading images of two different d3 graphs in single html page?

I created an html page for my tool which works offline(client side). This page is creating two different d3 based graph and I created two different buttons (save and save1)for each graph to downlaod images of these. These two image download button works fine, when tested separately in two different html pages.
Now, Problem in combined html page, is that each button is downloading the image of first d3 based graph only.
I defined two different svg variable (svg and svg1) for each graph creation but i donot know how to call it differently in downloadimage script.
**I think there is problem while calling "node( ).parentNode.innerHTML;" (mentioned in following svg downlaod script)?
But I don't know how to call different SVG in this script.
This is my first time, I am working on d3.
**
d3.select("#save1").on("click", function(){ //button save in first graph;
var html1 = d3.select("svg") //var html in first graph;
.attr("version", 1.1)
.attr("xmlns", "http://www.w3.org/2000/svg")
.node( ).parentNode.innerHTML;
//console.log(html);
var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html1);
var image = new Image;
image.src = imgsrc;
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.fillStyle = "#FFFFFF";
context.fillRect(0,0,image.width,image.height);
context.drawImage(image, 0, 0);
var a = document.createElement('a');
a.download = "image.png";
a.href = canvas.toDataURL('image/png');
document.body.appendChild(a);
a.click();
}
});
This line:
var html1 = d3.select("svg")
Is always selecting the first SVG in the DOM, regardless the button you click.
Instead of that, give your SVGs unique IDs (like svg1 and svg2), and select by those IDs:
var html1 = d3.select("#svg1")
var html2 = d3.select("#svg2")

Convert SVG dataUrl to base64

I'm using a plugin (dom-to-image) to generate a SVG content from a div.
It returns me a dataURL like this:
data image/xml, charset utf-8, <svg...
If a put this on a <img src the image is shown to normally.
The intent is to grab this dataURL, convert it to base64 so I can save it as an image.png on a mobile app.
Is it possible?
I tryied this solution https://stackoverflow.com/a/28450879/1691609
But coudn't get to work.
The console fire an error about the dataUrl
TypeError: Failed to execute 'serializeToString' on 'XMLSerializer': parameter 1 is not of type 'Node'.
==== UPDATE :: PROBLEM EXPLANATION/HISTORY ====
I'm using Ionic Framework, so my project is an mobile app.
The dom-to-image is already working cause right now, its rendering a PNG through toPng function.
The problem is the raster PNG is a blurry.
So I thought: Maybe the SVG will have better quality.
And it IS!! Its 100% perfect, actually.
On Ionic, I'm using 2 step procedure to save the image.
After get the PNG generated by the dom-to-img(base64) dataURL, I convert it to a Blob and then save into device.
This is working, but the final result, as I said, is blurry.
Then with SVG maybe it will be more "high quality" per say.
So, in order to do "minimal" change on a process that s already working :D I just need to convert an SVG into base64 dataURL....
Or, as some of you explained to me, into something else, like canvas...
I don't know any much :/
===
Sorry for the long post, and I really, really thank your help guys!!
EDIT COUPLE OF YARS LATER
Use JS fiddle for a working example: https://jsfiddle.net/msb42ojx/
Note, if you don't own DOM content (images), and those images don't have CORS enabled for everyone (Access-Control-Allow-Origin header), canvas cant render those images
I'm not trying to find out why is your case not working, here is how I did when I had something similar to do:
get the image sourcce (dom-to-image result)
set up a canvas with that image inside (using the image source)
download the image from canvas in whatever image you like: png, jpeg whatever
by the way you can resize the image to a standard format
document.getElementById('mydownload').onclick= function(){
var wrapper = document.getElementById('wrapper');
//dom to image
domtoimage.toSvg(wrapper).then(function (svgDataUrl) {
//download function
downloadPNGFromAnyImageSrc(svgDataUrl);
});
}
function downloadPNGFromAnyImageSrc(src)
{
//recreate the image with src recieved
var img = new Image;
//when image loaded (to know width and height)
img.onload = function(){
//drow image inside a canvas
var canvas = convertImageToCanvas(img);
//get image/png from convas
var pngImage = convertCanvasToImage(canvas);
//download
var anchor = document.createElement('a');
anchor.setAttribute('href', pngImage.src);
anchor.setAttribute('download', 'image.png');
anchor.click();
};
img.src = src;
// Converts image to canvas; returns new canvas element
function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
}
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
}
#wrapper{
background: red;
color: blue;
}
<script src="https://rawgit.com/tsayen/dom-to-image/master/src/dom-to-image.js"></script>
<button id='mydownload'>Download DomToImage</button>
<div id="wrapper">
<img src="http://i.imgur.com/6GvKdxY.jpg"/>
<div> DUDE IS WORKING</div>
<img src="http://i.imgur.com/6GvKdxY.jpg"/>
</div>
I translated #SilentTremor's solution into React/JS-Class:
class SVGToPNG {
static convert = function (src) {
var img = new Image();
img.onload = function () {
var canvas = SVGToPNG.#convertImageToCanvas(img);
var pngImage = SVGToPNG.#convertCanvasToImage(canvas);
var anchor = document.createElement("a");
anchor.setAttribute("href", pngImage.src);
anchor.setAttribute("download", "image.png");
anchor.click();
};
img.src = src;
};
static #convertImageToCanvas = function (image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
};
static #convertCanvasToImage = function (canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
};
}
export default SVGToPNG;
Usage:
let dataUrl = someCanvas.toDataURL("image/svg+xml");
SVGToPNG.convert(dataUrl);

Saving camanjs image after adding new layer

I am trying to download a canvas (with canvas.toBlob()) created with camanjs after it applies a new layer. I can only get it to download the image without the applied layer. I can right click and "save as..." to get the correct image but the downloaded file is incorrect.
Caman("#myImage", function() {
var canvas = document.getElementById('myImage');
var context = canvas.getContext('2d');
this.newLayer(function() {
var imageObj = new Image();
imageObj.src = "some_image.png";
imageObj.onload = function() {
context.drawImage(imageObj);
};
});
this.render(function() {
saveCanvas();
});
});
Try the below code snippet which converts the canvas image with multiple layers to base64 and save as JPEG. If you want to save in some other format like "png" then just
give "download.download = 'image.png'" in the below code
saveCanvas(){
var download = document.createElement('a');//Create <a> tag
download.href = document.getElementById('myImage').toDataURL(); //convert canvas image with multiple layers to base64
download.download = 'image.jpeg'; // Mention the file name and format to be downloaded
download.click();// Trigger click event to downkload the image
}

How to export multiple html tables and multiple d3 generated graphs into a single pdf

Basically I have multiple tables that are generated in html (also the data may vary depends on how much data are in the database, so I want the tables on pdf to be scalable as well, meaning no fixed size.) In addition, I have a d3 generated graph too on the same page.
What I want to know is..is there any way to turn everything displayed on the page into a pdf like a screenshot? I know there is phantomJS but it requires you to install and deploy on the local environment, and our project won't allow it.. so is there any 3rd party libraries that I can import and use to export them into a single PDF?
Please help
Using SaveSvg.js
https://gist.github.com/enjoylife/0ae74717a29862c5d8c5
and using jspdf was able to make it work
d3.select("#save").on("click", function(){
var html = d3.select("svg")
.attr("version", 1.1)
.attr("xmlns", "http://www.w3.org/2000/svg")
.node().parentNode.innerHTML;
//console.log(html);
var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);
var img = '<img src="'+imgsrc+'">';
d3.select("#svgdataurl").html(img);
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d");
var image = new Image;
image.src = imgsrc;
image.onload = function() {
context.drawImage(image, 0, 0);
//save and serve it as an actual filename
binaryblob();
var a = document.createElement("a");
a.download = "sample.png";
a.href = canvas.toDataURL("image/png");
/* Added as png to jspdf */
var doc = new jsPDF();
doc.addImage( a.href, "png", 0,0);
doc.save("test.pdf");
var pngimg = '<img src="'+a.href+'">';
d3.select("#pngdataurl").html(pngimg);
a.click();
};
});
jspdf alignment and css is good
http://plnkr.co/edit/nNSvHL8MZcT6nNKg9CG9?p=preview

Canvas.toDataURL() returns a file without extension

I'm converting an HTML canvas into a jpg when a save button is clicked. I use the code below:
$('#save').click(function(e){
var canvas = $('#myCanvas')[0];
var image = canvas.toDataURL("image/png").replace("image/png","image/octet-stream");
window.location.href=image; // it will save locally
});
Unfortunately, I download file without any extension. What I want is when I click the download button, The browser must download file from the page with a file extension.
Thanks
#K3N's answer didn't work for me because as mentioned:
Ideally you set the href before the click somehow.
I built on top of it and did this and it works great.
var btnSave = document.getElementById('btnSave');
btnSave.addEventListener('click', function() {
var image = photo.toDataURL("image/png");
var anchor = document.createElement('a');
anchor.setAttribute('download', 'myFilename.png');
anchor.setAttribute('href', image);
anchor.click();
});
Assuming your #save element is an anchor tag (<a ...></a>) you can do this:
$('#save').click(function(e){
var canvas = $('#myCanvas')[0];
var image = canvas.toDataURL("image/png");
$('#save').attr({
'download': 'myFilename.png', /// set filename
'href' : image /// set data-uri
});
});
Ideally you set the href before the click somehow.
You should use:
var canvas = document.getElementById("mycanvas");
var img = canvas.toDataURL("image/png");
for loading,you need to use:
document.write('<img src="'+img+'"/>');

Categories

Resources