Saving and automatically Download Canvas drawing using Javascript or ajax - javascript

I have a canvas drawing that I want to save and download automatically when a button is clicked. I will like to implement it in javascript or ajax as long as the saved data will be downloaded automatically. I do not need to save it to the server...
var canvas = document.getElementsByClassName('whiteboard')[0];
<canvas id='canvas' ></canvas>
<button id="scan" />Save</button>
Thanks

I am guessing that you don't need to save at all, just to download your drawing on canvas as image when button is clicked?
There are some good articles on that subject, but here is practical example of what you are trying to do (if my guess is true): Save canvas as image
So basically you add click event listener on your anchor tag with canvas image data uri as href attribute
link.addEventListener('click', function(ev) {
link.href = canvas.toDataURL();
link.download = "mypainting.png";
}, false);

Related

document.click in for-loop only work once?

I'm trying to download some object in the page from console. But it only save when I=3(last iteration), I think the problem may be the need to wait for downloads, but idk how to solve it.
First, the elements are render by canvas, so I turn them to image format.
Then, turn them into element, and click it to download.
I use the way in How to save a base64 image to user's disk using JavaScript?
But it only work in last iteration... any help? much thanks.
for(let i=1;i<=3;i++){
// load image
item_id = 'page'+i;
document.getElementById(item_id)
let image = document.getElementById(item_id).toDataURL("image/png").replace("image/png", "image/octet-stream");
// download image
var link = document.createElement("a");
document.body.appendChild(link);
link.setAttribute("href", image);
link.setAttribute("download", item_id+'.png');
link.click();
}

Force MP3 file to act as "Save as..." instead of playing in the browser

For a page which contains a list of mp3 files, I need to build a module for each listelement which has two button: a play and a download button. Clicking the play button, an mp3 player appears which plays audio in the browser as a fixed footer. I also need to provide a simple way for the user to download the file. The problem is that even if the audio tag contains a way to download (really download) the file, it does after clicking the more (3 dots) button. This is not what I want. I need to provide a direct download functionality for the download button. I started with the simplest approach:
//jsx
<a
target="_blank"
href={file.source}
download={file.name}
className="download-button"
type="application/octet-stream"
/>
(the last attribute: type is just from an answer I found for the problem, but doesn't make any change)
I've tried everything suggested, but the file still opens a new window and start to play the audio. The download attribute seems no longer working.
The second approach I was thinking of to define an audio tag istead of the a, define it without controls, and with JS, get the download attribute of it (as I saw a way how to split the features and build a custom player). But I haven't found a way to do it as .play() or .pause().
Are there any up-to-date way to force download on an audio file?
Here is a simple snippet to demonstrate using a blob to alter another blob's type.
For this is example I've use some HTML, and then make the blob into a html / text and then binary octect-stream for downloading.
const encoder = new TextEncoder();
const data = encoder.encode('This is <b>bold</b>');
function createLink(name, type) {
const a = document.createElement("a");
a.innerText = name;
document.body.appendChild(a);
document.body.appendChild(document.createElement('br'));
const blob = new Blob([data], {type})
const url = URL.createObjectURL(blob);
a.setAttribute('href', url);
}
createLink('HTML download', 'text/html');
createLink('TEXT download', 'text/plain');
createLink('Binary download', 'application/octet-stream');

How to send just uploaded image to php without store it?

Hi I'll introducing my problem directly with the use case: I'm working on a sort of configurator and I have a web page (let's call it page1) where the user can upload an image. The image is showed normally in an img tag. When the user has uploaded the image he can go forward on the next page (let's call it page2). Now, on this page2 I want to show the image uploaded by user without storing the image. This is what I've tried 'till now:
Before to do this I've inserted in the json the src attribute of the image directly. But the browser gave me te error that the GET request is too long or something like that. So, I've found as solution to convert the image with base64:
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
function sendSelectedProducts()
{
var logo = document.getElementsByName('logo-container')[0];
var base64 = getBase64Image(logo);
console.log(base64);
var json_string = '{"img": "' + base64 + '" }';
console.log(json_string);
window.location.replace('riepilogo.php?prodotti=' + json_string);
}
So, what I'm doing with this code is to send a Json with a base64-converted image. On the PHP-side this is the code that tries to convert back the image:
function base64ToImage($base64_string, $output_file) {
$file = fopen($output_file, "wb");
$data = explode(',', $base64_string);
fwrite($file, base64_decode($base64_decode));
fclose($file);
return $output_file;
}
echo '<p>'.$img.'</p>';
echo '<a class="cart-image" href="#"><img src="'.base64ToImage($img, 'logo_file.jpg').'" alt="logo"></a>'?>
This code doesn't work and I'm looking for solution that does not store the image on the server. How can I do?
You don't need to decode the image from base64, just do this:
echo '<a class="cart-image" href="#"><img src="data:'.$img.'" alt="logo"></a>'?>
where $img is the image in base64 format. For more info see: How to display Base64 images in HTML?
You can save the selected file (for example in a window var or local storage) and render the image in the next page using canvas.
See following example, please:
function saveImage(img) {
window.file = img.files[0];
}
function loadImage() {
let ctx = document.getElementById('canvas').getContext('2d');
let url = URL.createObjectURL(window.file);
let img = new Image();
img.onload = function() {
ctx.drawImage(img, 20, 20);
}
img.src = url;
}
<input type="file" id="imgFile" onchange="saveImage(this);" />
<button onclick="loadImage()">Load image</button>
<canvas width="400" height="300" id="canvas"/>
You should put saveImage in the first page and loadImage in the second page.
I hope it was clear. Bye.
You need to know how HTTP works to understand why what you're doing is not going to work.
HTTP is the way browsers and Web servers (which can run PHP code) communicate.
One important thing to keep in mind here is that between any two Web pages there is no state to share for the Web server -- this is why HTTP is often called a stateless protocol. That's a good thing -- it saves on a lot of unneeded complexity for the Web server (and PHP).
I would not recommend attempting to circumvent the stateless nature of HTTP with things like window.localStorage (or sessionStorage for that matter) -- what if the user has loaded several instances of the same Web page on your website? How are you going to know which objects in your storage correspond to which upload workflow(s)?
I've seen many people try to do that, and it always breaks eventually.
There are several good ways to solve the "stateless" problem in your case -- how can a file uploaded with one Web page, be accessible to another, and yet making the file also available to the Web server?
In this answer I want to cover a so-called single Web page application solution, where you simply do away with two Web pages and instead have one Web page that does everything! This way you keep the state on the client but also in a clean manner that aligns well with how HTTP actually works:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form enctype="multipart/form-data" method="post" action="http://httpbin.org/post">
<label for="file-input">Select an image file</label>
<input accept="image/*" id="file-input" name="image" type="file">
<label for="file-selection-preview-image">Selected image</label>
<img id="file-selection-preview-image"><!-- this element will display selected image. -->
<input type="submit">
<script>
const form = document.currentScript.parentElement, file_input = form.elements.image;
file_input.addEventListener("change", function(ev) { /// Whenever the selection changes
const files = ev.target.files;
console.assert(files.length == 1); /// Assert that there is only one file selected
console.assert(files[0].type.startsWith("image/")); /// Assert that the selected file is an image
const image = form.querySelector("img");
if(image.src) URL.revokeObjectURL(image.src); /// The kind of URLs we are dealing with refer to in-memory objects, so we have to dispose of them when we no longer need them -- the user agent does not do this for us automatically.
image.src = URL.createObjectURL(files[0]); /// Display selected file with the `img` element
});
/// User agent is free to retain file selection even after the Web page has been re-loaded, so if there is [a selection], we fire a "change" event manually so that the handler defined above may reflect this as it ordinarily would.
if(file_input.files.length) file_input.dispatchEvent(new Event("change", { bubbles: true }));
</script>
</form>
</body>
</html>
The above HTML document is set up with a simple form (which will let you upload files to your Web server even without JavaScript enabled). It contains a file input control that lets you actually select files (a single image file, since the input element does not contain the multiple attribute and specifies image/* for the accept attribute).
However, it also contains an img element which a script uses to load and display the selected image file with, immediately upon selection. I understand from your question that this may satisfy your requirement of accessing the selected file. The file is a Blob so you can do what you want with it, including drawing it in a canvas and modifying it otherwise. Here I just display it as an image.
The interesting property of the Web page is that while preview of the selected image only works through JavaScript, the form will still submit the selected file even without JavaScript. The user agent will post form data (image) to a convenient test server (at http://httpbin.com/post), which just happens to echo back your uploaded content in the form of a JSON file. With own service, you can handle the data yourself.
This solves the problem of multiple Web pages needing to share access to selected file, which would, if implemented properly, at least require uploading the file first and then accessing it from a URL the upload establishes on your Web server. Not necessarily more complicated than the solution in this answer, in fact arguably less complicated because it's how it has been done before JavaScript started allowing the kind of things I make use of in the document pasted above. But I would argue that this answer that covers a so-called single-page Web application, should fit you fine in this day and age.
That said, I consider a pure PHP solution to be interesting as well, and can pen up another answer should anyone wish to see one.

How to preload image offscreen and then move to different onscreen element?

I'm building a website/app that will display six different images at a time. The contents of those images are loaded from another site and changing regularly. Where any particular image goes on screen depends on the state of all images already on screen.
To get the image I use jQuery to change the src attribute of one of the 6 img locations, then wait for the load using jQuery load(), then show it. However, this means I have to pick my location before the image is loaded. The problem I'm having is that between the time I initiate the load and when the image finally does load, the proper location for that image might have changed.
So my question is whether there's a way to load the image offscreen (say in a hidden img), and then, when it's loaded, get a notification of it being finished and then move that image to the correct location at that moment.
I've found lots of preload questions and answers on StackOverflow, but they all presume you know where you want the image to go when you initiate the load.
Update: thinking more on this question, perhaps another way of framing it is 1) if I load an image from an offsite server into an offscreen/hidden img and wait for it to load, 2) would subsequently setting the src attribute of an onscreen/visible img to the same image URL draw from the server or the browser cache? In other words, if I load a remote image offscreen does the next request for that same image go back to the server or to the browser cache (and would this be consistent for all browsers)?
One Way to do it:
function loadImg(url, callback, key) {
var image = new Image();
image.onload = function() {
callback(image, key)
};
image.onerror = function() {};
image.src = url;
}
function imageOnload(image, key) {
imageGoesTo[key].src = image.src
}
var imageGoesTo = {
"firstPicture": document.getElementById("img1"),
"secondPicture": document.getElementById("img2"),
}
loadImg("http://7pi.azurewebsites.net/img/DSC09906.jpg", imageOnload, "firstPicture")
imageGoesTo["secondPicture"] = document.getElementById("img3")
loadImg("http://7pi.azurewebsites.net/img/DSC07934.jpg", imageOnload, "secondPicture")
<img id="img1" alt="loading">
<img id="img2" alt="loading">
<img id="img3" alt="loading">

HTML image render notification

In one webpage, I have a big image to load and other contents. Sometimes the image takes longer time to load and I would like to track that. Is there any means by which I can get notified using Javascript when browser completely renders the image?
EDIT
I use the following code to load the image.
<table border="0" style="background-image: url(http://abc.com/abc.jpg);" id="imageDisp">
</table>
SOME More UPDATE
Is there any simple way to know how long the image took to render? Using the javascript I am getting a notification that the image is loaded now, is there a way to know when the image load started? So that the elapsed time can be calculated?
You can hook on the load event of the <img> element. E.g.
<img src="http://upload.wikimedia.org/wikipedia/commons/3/31/Atlantic_hurricane_tracks.jpg"
onload="alert('finished!');">
Jsfiddle demo.
Update:
Then create new Image() instead (the average browser is smart enough not to request the same image twice and multiple references will point to the same image request):
<script>
var img = new Image();
img.src = 'http://upload.wikimedia.org/wikipedia/commons/3/31/Atlantic_hurricane_tracks.jpg';
img.onload = function() {
alert('finished!');
}
</script>
Another jsfiddle demo (don't forget to clear browser cache, the same image might be already cached :) ).

Categories