In my application I'm using html2canvas for converting a HTML in to canvas and after that i'm converting that canvas to image using toDataURL() every thing fine in chrome the image is downloading soon after the page loads, but in safari the image loading in a the same page without downloading.
$(document).ready(function(e) {
html2canvas(document.body, {
onrendered: function(canvas) {
var test = document.getElementsByClassName('test'); //finding the div.test in the page
$(test).append(canvas); //appending the canvas to the div
var canvas = document.getElementsByTagName('canvas');
$(canvas).attr('id','test'); //assigning an id to the canvas
var can2 = document.getElementById("test");
var dataURL = can2.toDataURL("image/png");
document.getElementById("image_test").src = dataURL; //assigning the url to the image
$(canvas).remove(); //removing the canvas from the page
download(can2,'untitled.png');
function download(canvas_name,filename)
{
var tempLink = document.createElement('a');
e;
tempLink.download = filename;
tempLink.href = dataURL;
if (document.createEvent) // create a "fake" click-event to trigger the download
{
e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window,0, 0, 0, 0, 0, false, false, false,false, 0, null);
tempLink.dispatchEvent(e);
}
else if (tempLink.fireEvent)
{
tempLink.fireEvent("onclick");
}
}
},logging:true,background: "#fff",
});
});
Can anybody help me what i nee to change to download the file in Safari?
iOS limitations
The iOS there are limitations which prevent direct download (practically almost all formats), where images can be downloaded holding the "touch".
The best alternative to this would be to open an "alert" with instructions and after the alert to close call "window.open" with the image.
See the code with an alternative to "iOS"
BUG in Safari (PC and MAC - non iOS - is no problem in webkit technology, but in the browser)
I tried append anchor, create "ghost-iframe" and replace mimetype: application/download.
Download manager open, but not add file after click in "Save" or "Open".
In my opinion this is a BUG in Browser (not is an issue of Webkit, the issue is of Safari).
See code:
$(document).ready(function(e) {
var ghostFrame = document.createElement("iframe");
ghostFrame.name = "myFrame";
document.body.appendChild(ghostFrame);
html2canvas(document.body, {
onrendered: function(canvas) {
var test = document.getElementsByClassName('test'); //finding the div.test in the page
$(test).append(canvas); //appending the canvas to the div
var canvas = document.getElementsByTagName('canvas');
$(canvas).attr('id','test'); //assigning an id to the canvas
var can2 = document.getElementById("test");
var dataURL = can2.toDataURL("image/png");
document.getElementById("image_test").src = dataURL; //assigning the url to the image
$(canvas).remove(); //removing the canvas from the page
var tempLink = document.createElement('a'), e;
tempLink.download = 'untitled.png';
if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent)) { //iOS = Iphone, Ipad, etc.
alert("Instructions...");
tempLink.target = "_blank";
tempLink.href = dataURL;
} else {
tempLink.target = ghostFrame.name;
tempLink.href = dataURL.replace(/^data[:]image\/png[;]/i, "data:application/download;");//force download
}
if (document.createEvent) // create a "fake" click-event to trigger the download
{
e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
tempLink.dispatchEvent(e);
} else if (tempLink.fireEvent) {
tempLink.fireEvent("onclick");
}
},
logging:true,
background: "#fff",
});
});
Alternative solution (not work in iOS):
You will have to upload the file to the server and then set the required headers for download, see:
Upload image
Download image with .htaccess (add "htaccess" just the folder that the images are generated by <canvas>.toDataURL)
Download image with PHP
Related
I am building a site that allows users to create customized graphics and then download them directly from the page.
I am doing this via the user customizing an svg via a javascript powered form which is then made into a PNG before downloading.
However, now I want to store a copy of the png that the user created so that I can display it on the site's home page. What is the best way to store a copy of the dynamically created graphic? AJAX? HTTP Request? Both are very foreign topics to me so I am unsure how to go about it from here.
For reference here is the code that builds the PNG from the svg and then triggers the download for the user.
var svg = document.getElementById("bg2");
var canvas = document.querySelector("canvas");
function triggerDownload (imgURI) {
var evt = new MouseEvent('click', {
view: window,
bubbles: false,
cancelable: true
});
if(document.getElementById("name").value=="null" || document.getElementById("name").value=="") {
var un = "MakeAGraphic";
} else {
var enteredName = document.getElementById("name").value.replace(/[^a-zA-Z ]/g, "");
var un = `${enteredName}_MakeAGraphic`
}
var a = document.createElement('a');
a.setAttribute('download', `${un}.png`);
a.setAttribute('href', imgURI);
a.setAttribute('target', '_blank');
a.dispatchEvent(evt);
}
btn.addEventListener('click', function () {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var data = (new XMLSerializer()).serializeToString(svg);
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
var imgURI = canvas
.toDataURL('image/png')
.replace('image/png', 'image/octet-stream');
triggerDownload(imgURI);
};
img.src = url;
});
agree to that answer mentioned by #showdev .
Call
canvas.toBlob(callback, mimeType, qualityArgument);
then call
formData.append("an-image", blob);
then upload formData using the AJAX or fetch API.
see the documents at
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I found and edited below code to save my html5 canvas as a .png-image. The canvas is generated by Three.js/Potree.
This code works perfectly. But, I want a higher resolution image as an output. Usually, the THREEjs renderer is sized according to the clients browser size. I have already manually enlarged it to 3000x2000. This edit will give a higher-resolution image, but when increasing more no effects are visible anymore.
Is there a simple (I'm not that into javascript..) workaround for downloading a high-resolution output image?
At first, the images are just for me. No user needs to download it or needs to pass it onto the server. Although, if its a neat solution, I'd like to give the user the possibility to save their image as well.
function saveAsImage() {
var strDownloadMime = "image/octet-stream";
//alert("function saveimage")
var imgData, imgNode;
try {
var strMime = "image/png";
imgData = viewer.renderer.domElement.toDataURL(strMime);
saveFile(imgData.replace(strMime, strDownloadMime), "test.png");
} catch (e) {
console.log(e);
return;
}
}
var saveFile = function (strData, filename) {
//alert("savefilefunction");
var link = document.createElement('a');
if (typeof link.download === 'string') {
document.body.appendChild(link); //Firefox requires the link to be in the body
link.download = filename;
link.href = strData;
link.click();
document.body.removeChild(link); //remove the link when done
} else {
location.replace(uri);
}
}
THREE Renderer settings:
let width = 3000;
let height= 2000;
this.renderer = new THREE.WebGLRenderer({premultipliedAlpha: false, preserveDrawingBuffer: true});
this.renderer.setSize(width, height);
I have a button, Printer Friendly, which creates a screenshot of a table within the Route Check In tab. I have another tab, LCP, where I would like the same button to capture a screen shot of this page when I go the LCP tab.
Here is the code within rollup.js where the html2canvas is created when you click the Printer Friendly button.
app.controller('Rollup', function($scope, $rootScope, $http, $uibModal, headersvc, locFiltersvc) {
.....
$scope.printDiv = function(divName) {
html2canvas(document.getElementById("routeContent"), {
onrendered: function (canvas) {
var img = canvas.toDataURL("image/png");
var doc = new jsPDF();
doc.addImage(img, 'JPEG',1,30,210,230);
//HEADER TEST
doc.text(5, 5, "Header");
doc.save('Route.pdf');
//OPEN IN NEW WINDOW TEST
//doc.output('dataurlnewwindow');
//IE 9-11 WORK AROUND
if (navigator.userAgent.indexOf("MSIE ") > 0 ||
navigator.userAgent.match(/Trident.*rv\:11\./))
{
var blob = canvas.msToBlob();
window.navigator.msSaveBlob(blob,'Test file.png');
}
},
});
//html2canvas for LCP tab
/*
html2canvas(document.getElementById("divPrint"), {
onrendered: function (canvas) {
//document.body.appendChild(canvas);
var img = canvas.toDataURL("image/png");
var doc = new jsPDF();
//alters size of the pdf preview
//doc.addImage(img, 'JPEG',1,1,205,100);
doc.addImage(img, 'JPEG',1,1,210,110);
doc.save('LCP.pdf');
//IE 9-11 WORK AROUND
if (navigator.userAgent.indexOf("MSIE ") > 0 ||
navigator.userAgent.match(/Trident.*rv\:11\./))
{
var blob = canvas.msToBlob();
window.navigator.msSaveBlob(blob,'Test file.png');
}
},
});
*/
}
});
How can I combine both to work when I click the button within the specific tab? Thanks.
I also want the screen shot to open in a new tab rather than the screenshot saving as a pdf.
Any help is appreciated.
Currently i am working on a open webapp camera, right now i have implemented the camera setup(live stream as viewport, take picture button, capture, display taken picture in corner... etc) but now i am running into the issue of how to save that picture for the user to their device or computer, this app is currently being designed for mobile b2g primarily. I know most people are gonna tell me security issues!!! i dont mean tell the device exactly where to put it. I mean something like
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script type="text/javascript">
window.onload = function () {
var img = document.getElementById('embedImage');
var button = document.getElementById('saveImage');
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA'+
'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO'+
'9TXL0Y4OHwAAAABJRU5ErkJggg==';
img.onload = function () {
button.removeAttribute('disabled');
};
button.onclick = function () {
window.location.href = img.src.replace('image/png', 'image/octet-stream');
};
};
</script>
</head>
<body>
<img id="embedImage" alt="Red dot"/>
<input id="saveImage" type="button" value="save image" disabled="disabled"/>
</body>
</html>
that specific code executed on mobile triggers the file to automatically be saved on click of the button. now what i want to do is use that to take my picture from its var its in and save it as that file, for example that will be in downloads folder.
this is what my code is currently https://github.com/1Jamie/1Jamie.github.io
any help would be appreciated and this is the current running implementation if you want to take a working look http://1Jamie.github.io
This worked for me when I was playing around with getUserMedia - I did notice that you did not have the name of the method in the proper case and it is a method of the navigator.mediaDevices interface - not a method of the window directly...
References:
[Navigator for mozilla]https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS/API/Navigator
https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices
[mediaDevices for chrome and android]https://developers.google.com/web/updates/2015/10/media-devices?hl=en
var video = document.getElementById('monitor');
var canvas1 = document.getElementById('photo1');
var img1 = document.getElementById('canvasImg');
navigator.mediaDevices.getUserMedia({
video: true
}).then(function (stream) {
video.srcObject = stream;
video.onloadedmetadata = function () {
canvas1.width = video.videoWidth;
canvas1.height = video.videoHeight;
document.getElementById('splash').hidden = true;
document.getElementById('app').hidden = false;
};
}).catch(function (reason) {
document.getElementById('errorMessage').textContent = 'No camera available.';
});
function snapshot1() {
canvas1.getContext('2d').drawImage(video, 0, 0);
}
"save_snap" is the id of a button - Disclaimer I am using jQuery- but you should easily see where this corresponds to your code:
$("#save_snap").click(function (event){
// save canvas image as data url (png format by default)
var dataURL = canvas2.toDataURL();
// set canvasImg image src to dataURL
// so it can be saved as an image
$('#canvasImg').attr("src" , dataURL);
$('#downloader').attr("download" , "download.png");
$('#downloader').attr("href" , dataURL);
//* trying to force download - jQuery trigger does not apply
//Use CustomEvent Vanilla js: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
// In particular
var event1 = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
//NOW we are effectively clicking the element with the href attribute:
//Could use jQuery selector but then we would have to unwrap it
// to expose it to the native js function...
document.getElementById('downloader').dispatchEvent(event1);
});
I'm working on a multi part html questionnaire style form that has a lot of text questions along with a few images. On questions that are images the user is selects the image, i create a canvas element and display the resized image in it underneath the file input.
if (window.FileReader)
{
var file = element.files[0];
var $input = $(element);
var $fileName = file.name;
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement("img");
img.src = e.target.result;
var dataID = $input.data("questionId");
var canvasID = "canvas_" + dataID;
$("#"+canvasID).remove();
var canvas = document.createElement("canvas");
canvas.setAttribute("id", canvasID);
canvas.setAttribute("height", "200");
canvas.setAttribute("width", "200");
var heightWidth = getHeightWidth(img);
canvas.height = heightWidth[0];
canvas.width = heightWidth[1];
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0, canvas.width, canvas.height);
var sectionID = "section_" + dataID;
$("#" + sectionID).append(canvas);
$("#file_title-" + dataID).val($fileName);
}
reader.readAsDataURL(file);
}
else
{
alert("This browser does not support image uploading.");
}
This works fine in chrome but not in safari (safari 8.x) on desktop or iOS. The problem in my code is that on Safari it returns height=0 width=0 from getHeightWidth() which gives me think the img isn't ready to be handled yet. This theory is further validated because if i change to a new picture and change back to the original it displays properly.
I'm really not sure where to start, any help debugging this would be greatly appreciated. Thanks everyone
The code assumes the image loading is synchronous, but it's asynchronous and should be assumed so even with data-URIs. If the image hasn't loaded properly its width and height attributes will be 0.
You can solve this by adding an onload handler for img, then move the code for detecting and setting size inside that handler (remember also to add an onerror handler as well in case the image file is corrupted).