I am trying to convert a canvas to image. The code used is as follows.
var canvas = document.getElementsByTagName("canvas")[0]
var context = canvas.getContext('2d');
url = canvas.toDataURL().replace(/^data:image\/[^;]/, 'data:application/octet-stream');
window.open(url);
The above code saves the image on the downloads folder. I need to save the image on a specific folder(Eg: /home/username/Desktop/projects/MyProject1/images/).
Any ideas on how this could be done?
Related
So, I have a user input which serve to upload pictures. This is a simple example:
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
console.log (img);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
<input type="file" onchange="handleImage(event)"><br>
As you can see, I display an Image () on the console. I want to convert this Image into a jpg file.
I understood how to get the pixels of the picture but it's completely crazy to send it to a server: It's to large!
I also tried to access to the jpg file stored in the computer but I do not achieve to anything.
The only way I found is to send it with a form like this:
<form action="anything.php" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
</form>
And in PHP:
$_FILES["fileToUpload"]["tmp_name"]
Why not with JS?
My final goal is to send the jpg file with AJAX.
Tell me if you have some questions.
The simplest way is to use a canvas element and then invoke a download action allowing the user to select where to save the image.
You mention that the image is large, but not how much - be aware that with canvas you will also run into restrictions when the image source starts to touch around the 8k area in pixel size.
A simplified example (IE will require a polyfill for toBlob()).:
Load image source via input
Use File blob directly as image source via URL.createObjectURL()
When loaded, create a temporary canvas, set canvas size = image size and draw in image
Use toBlob() (more efficient on memory and performance and require no transcoding to/from Base64) to obtain a Blob.
We'll convert the Blob to File (a subset object and it will reference the same memory) so we can also give a filename as well as (important!) a binary mime-type.
Since the mime-type for the final step is binary the browser will invoke a Save as dialog.
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
c.toBlob(function(blob) {
var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
window.location = URL.createObjectURL(file);
}, "image/jpeg", 0.75); // mime=JPEG, quality=0.75
}
// NOTE: toBlob() is not supported in IE, use a polyfill for IE.
<label>Select image to convert: <input type=file></label>
Update: If you just are after a string (base-64 encoded) version of the newly created JPEG simply use toDataURL() instead of toBlob():
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
var jpeg = c.toDataURL("image/jpeg", 0.75); // mime=JPEG, quality=0.75
console.log(jpeg.length)
}
<label>Select image to convert: <input type=file></label>
JavaScript on the client side can not save files.
You have multiple options:
Render the image on an <canvas> element. This way it can be saved with right click -> save image
Inset the image as <img> element. This way it can be saved with right click -> save image
Send the image data as base64 string to the server. Do the processing there
Use a server side language like PHP or Node.js to save the file
Long story short, you have to use some server side logic to save the file on disk
I have a canvas and need to save it to the local disk. AFAIK writing to disk is not possible by Javascript. Therefore I consider saving the canvas on the server (I know how to do this) and automatically initiate a download as described here:
How to Automatically Start a Download in PHP?
Is there a more straight-forward solution for this procedure?
Yes, you can create image downloads on the client side now. The browser handles the interaction with the client's filesystem. There is a library called download.js which makes the process easy.
var data = canvas.toDataURL();
var fileName = "myCoolPicture.png";
var strMimeType = 'image/png';
download(data, fileName, strMimeType);
How to get a dataURI from an SVG image
function getSVGDataURL(svg){
return "data:image/svg+xml;utf8,"+svg.outerHTML;
}
var svg = document.getElementById('svg');
var dataurl = getSVGDataURL(svg);
So I am using mongoDB as my database and I have saved an image in mongoDB in binary format.
The image below is how the data is being displayed in my database.
I have tried the following:
<img src="data:image/jpeg;base64{<%= user.img.data %>}"/>
But the above code does not seem to work. Please note I am using EJS as a tempting engine.
After doing the inspect element on google chrome I found that the data was being shown like so:
I am not sure how to read this binary image and display it in a img tag in html.
UPDATE:
After making the changes recommended by Alex Matos in the comments I get the following output:
If you really got the images data and saved it i mongo db, you could render the image in a canvas and append it wherever you need.
// Renders the image data in a canvas off screen
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var data = ctx.putImageData(YOUR_MONGODB_DATA,0,0);
// Initializes a new image from canvas and appends it to the parent you want
var image = new Image();
image.id = "rendered-picture"
image.src = canvas.toDataURL();
document.getElementById('PARENT_ID').appendChild(image);
Try returning data from your server using base64_encode.
For example:
<?php
$picture = base64_encode(user.img.data);
<img src="data:image/jpeg;base64{<%= picture %>}"/>
?>
I have one problem with HTML5 Canvas.
I have one image. On this image I want to put text and display/save this as an image.
I have this code:
window.onload = function(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function(){
context.drawImage(imageObj, 10, 10);
context.font = "20px Calibri";
context.fillText("My TEXT!", 50, 200);
};
imageObj.src = "mail-image.jpg";
};
This works fine. There is my image and the text on it.
But it is still a canvas and no image.
Can anybody help me?
For security reasons, there's no convenient way of saving a canvas drawing to a user's local drive.
As a workaround, go "old school": Convert the canvas to an image and display it in a new window.
window.onload = function(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function(){
context.drawImage(imageObj, 10, 10);
context.font = "20px Calibri";
context.fillText("My TEXT!", 50, 200);
// open the image in a new browser tab
// the user can right-click and save that image
var win=window.open();
win.document.write("<img src='"+canvas.toDataURL()+"'/>");
};
imageObj.src = "mail-image.jpg";
};
Sand boxing
Browsers are sand-boxed when it deals with saving content to user's hard disk. This is for security (you don't want a bad hacker (or spy) to overwrite system files or plant a virus or a backdoor etc.). So direct access is prevented and local storage is isolated.
You always need to "bridge" the content by an user interaction that approves the operation and therefor the browser will request you to choose a location for the file by popping up a dialog to make the user aware of that the browser tries to deliver content to be saved (see demo below).
Invoking save dialogs
Here are a couple of other possibilities to enable download.
If a link for example under the image is ok then you can do:
/// create an anchor/link (or use an existing)
var lnk = document.createElement('a');
/// set your image as data-uri link
lnk.href = canvas.toDataURL();
/// and the key, when user click image will be downloaded
lnk.download = 'filename.png';
/// add lnk to DOM, here after the canvas
canvas.parentElement.appendChild(lnk);
The download attribute is a new HTML5 feature. Instead of "navigating" to this location the browser will show a save dialog instead and let the user save its content to disk.
You can also automate the whole clicking feature by generating an event for it.
For example:
function download(canvas, filename) {
if (typeof filename !== 'string' || filename.trim().length === 0)
filename = 'Untitled';
var lnk = document.createElement('a'),
e;
lnk.download = filename;
lnk.href = canvas.toDataURL();
if (document.createEvent) {
e = document.createEvent("MouseEvents");
e.initMouseEvent('click', true, true, window,
0, 0, 0, 0, 0, false, false,
false, false, 0, null);
/// send event
lnk.dispatchEvent(e);
} else if (lnk.fireEvent) {
lnk.fireEvent("onclick");
}
}
Saving to server
You can always go by the step of saving the file to a server. However, you will also have to go through the save dialog step when retrieving the file from server (the dialog).
If you want to store the file only to be shown in the browser this is perfect.
There are various ways to do this (there are many solutions on SO for this).
Local storage
And a different option is to store the file in the browser's local storage. You have Web Storage, however this is very limited (typically between 2.5 - 5 mb) and considering that each char stored takes two bytes the actual storage is just half of that (it can only store strings such as the data-uri and data-uris is about 33% larger than the original file). But if you save small icons, sprites etc. this might do.
In addition you can use Indexed DB (and the now deprectaed Web SQL) which can store larger data and you can also request user's permission to store x mb of dat.
The same goes with File API (which is currently only implemented in Chrome). This acts more like a file system and is intended to store huge files.
These might seem more complex if you are not familiar with them, but I mention them as possible options as these also saves you bandwidth communicating with a server and you move the "burden" to the client instead of the server.
I need the help on the below two things
1) I need to convert the PDF file data to bytes arrray in JavaScript .
2) Using the above bytes array, I need to render it in the UI as PDF file.
Questions may look like, why I want to convert the PDF file to bytes Stream and again why I want to show it as PDF in UI. But I need to figure out a way for the above two which helps me to solve many issues in my project.
Any suggestions for reading or solutions to above problems will be much appreciable.
Thanks for your time!
please check pdf.js.
it may be helpful
http://mozilla.github.io/pdf.js
Following code will read the file locally and render the PDF. This will be faster as File doesn't have to get uploaded to server and get downloaded to browser again.
<script type="text/javascript">
//Workaround for a bug on IE.
PDFJS.workerSrc = "pdf.worker.js";
//File from the input element
inputElement.onchange = function(event) {
var file = event.target.files[0];
//Read the file locally using file reader
var fileReader = new FileReader();
fileReader.onload = function() {
var typedarray = new Uint8Array(this.result);
// Render PDF
PDFJS.getDocument(typedarray).then(function(pdf) {
pdf.getPage(1).then(function getPageHelloWorld(page) {
var scale = 1.5;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({canvasContext: context, viewport: viewport});
});
});
};
// Read the file into array buffer.
fileReader.readAsArrayBuffer(file);
}
</script>