I selected a svg file and read it via readDataUrl(<file>), I can set it to an html image element by setting the src to be the value read from the file. However the width and height attributes will be 0. How can I set the value read from a file to an svg element in order to be able to do a getBBox().width to obtain its width?
You can use XMLHttpRequest (or your favourite AJAX library) to read and parse the SVG file. I imagine you can even just pass the dataurl to it if you want.
Edit, because I misread the question :
If you can append the svg to your document, and need to use a FileReader, use its readAsText() method, then insert it in an html element.
function previewFile() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.onloadend = function () {
var parent = document.getElementById('container');
parent.innerHTML= reader.result;
}
if (file && file.type=="image/svg+xml") {
reader.readAsText(file);
} else {
alert("wrong file type or no file provided");
}
}
<div id="container"></div>
<input type="file" onchange="previewFile()">
If you don't need to use a FileReader (e.g if the file is saved on the server), Paul's answer is better.
If you don't want to actually append the svg file but only know its width/height, you can refer to my
original answer :
I don't think you can get the height from the data url.
As a workaround, you can use the readAsText()method of the fileReader API, combined with the DOMParser() method, in order to read the viewBox property of the svg.
function xlog(msg){
document.getElementById('log').textContent = msg;
}
function previewFile() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.onloadend = function () {
var doc = new DOMParser().parseFromString(reader.result, 'application/xml');
var viewBox = doc.documentElement.viewBox.baseVal;
xlog('height:'+viewBox.height+' width:'+viewBox.width);
}
if (file && file.type=="image/svg+xml") {
reader.readAsText(file);
} else {
xlog("wrong file type or no file provided");
}
}
<p id="log"></p><br>
<input type="file" onchange="previewFile()">
Note that you can append the doc.documentElement into your document and then get the element's BBox.
Related
This question already has answers here:
Check image width and height before upload with Javascript
(11 answers)
Closed 1 year ago.
I have an image upload box. Standard stuff:
<input id="image-upload-input" type="file" />
Once the user picks a file, I can access the contents and send it to my API over Axios like such:
const imageUploadInput = document.getElementById("image-upload-input");
const file = imageUploadInput.files[0];
if (!file) {
return;
}
const reader = new FileReader();
const component = this;
reader.onload = function (event) {
axios.post("upload/image", Buffer.from(event.target.result));
};
reader.readAsArrayBuffer(file);
However, I have some restrictions regarding dimensions and would like to check those on the client side.
I am fairly certain it can be done. I haven't tried it yet but I imagine if I just pop the data into an (ideally invisible) img tag with a data src attribute, that might work. Does anyone have any working code? Or a better way to do it?
adding something like this should work
imageUploadInput.onchange = function (event) {
const file = imageUploadInput.files[0];
if (!file) {
return;
}
const image = new Image();
image.onload = function() {
console.log(this.width, this.height);
}
image.src = URL.createObjectURL(file);
};
I'm building a program that allows the user to choose an image to upload. Once the user chooses one, it triggers the previewFile() function, which uses FileReader to display the image.
Now I'm building a function that will download the same image that the user uploaded (and add some style changes). First, I created a new image element, but now I'm stuck, since I can't figure out how to reference the src value of the original image. Once I do get the src value, I can finish adding the styles, then download the edited image.
Here's what I have so far - can anyone help me out?
HTML:
<input type="file" onchange="previewFile()">
<img src="" alt="Preview File...">
JavaScript:
function previewFile() {
const preview = document.querySelector('img');
const file = document.querySelector('input[type=file]').files[0];
const reader = new FileReader();
reader.addEventListener("load", function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
And the function I need help with:
function createAndDownload() {
const editedImage = document.createElement('img');
/*
Here's where I need help: I need to figure out how to get the image src
from the original image, and set it equal to editedImage.src
*/
//add styles
//download editedImage
}
You assigned it this way:
const preview = document.querySelector('img');
preview.src = reader.result;
So you do the same thing to read it back:
const preview = document.querySelector('img');
const something = preview.src;
I have found code for reading multiple images on the
internet.
Here is the code:
HTML
<input id="browse" type="file" onchange="previewFiles()" multiple>
JavaScript
function previewFiles() {
var preview = document.querySelector('#preview');
var files = document.querySelector('input[type=file]').files;
function readAndPreview(file) {
// Make sure `file.name` matches our extensions criteria
if ( /\.(jpe?g|png|gif)$/i.test(file.name) ) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = this.result;
preview.appendChild( image );
}, false);
reader.readAsDataURL(file);
}
}
if (files) {
[].forEach.call(files, readAndPreview);
}
}
I have a problem with it, as I do not fully understand what is happening and why it does not preview/seems like it is storing multiple files.
The main problem in the included code is that there is no element with the id preview (ref: var preview = document.querySelector('#preview');)
Adding this and it will work. However, you can skip FileReader as it isn't needed. Instead treat the File as a Blob (they are essentially the same) and use createObjectURL() with it - the performance and the memory footprint are significant better in case you want to display a high amount of images.
document.querySelector('#browse').onchange = function() {
var preview = document.querySelector('#preview');
[].forEach.call(this.files, function(file) {
if (/image\/.*/.test(file.type)) { // use any image format the browser can read
var img = new Image;
img.onload = remURL; // to remove Object-URL after use
img.style.height = "100px"; // use style, "width" defaults to "auto"
img.src = (URL || webkitURL).createObjectURL(file);
preview.appendChild(img); // add image to preview container
}
});
function remURL() {(URL || webkitURL).revokeObjectURL(this.src)}
};
<input id="browse" type="file" multiple>
<div id=preview></div> <!-- an element with this ID was missing -->
Your final lines of code:
if (files) {
[].forEach.call(files, readAndPreview);
}
Should do nothing. It goes for each over an empty array.
I think you were trying to do something like:
files.forEach(readAndPreview)
Which would actually go over all of the files in the files array and call readAndPreview for them.
I have a div containing an image and some text. The user is able to customize it. Once his modifications are done, I would like to save the div as an image with the text on it.
Just like if he took a screenshot.
I am able to save images from Base64 strings in my PHP side but I can't get the correct Base64 from the HTML.
So, I would like to know how to get the base64 from the HTML inside my div, using JavaScript or jQuery. I could also add plugins.
Try
var elem = $("div")[0].outerHTML;
var blob = new Blob([elem], {
"type": "text/html"
});
var reader = new FileReader();
reader.onload = function (evt) {
if (evt.target.readyState === 2) {
console.log(
// full data-uri
evt.target.result
// base64 portion of data-uri
, evt.target.result.slice(22, evt.target.result.length));
// window.open(evt.target.result)
};
};
reader.readAsDataURL(blob);
jsfiddle http://jsfiddle.net/guest271314/9mg5sf7o/
Try html2canvas
http://html2canvas.hertzen.com/examples.html
html2canvas($("#div"), {
onrendered: function(canvas) {
var myImage = canvas.toDataURL("img/png");
window.open(myImage);
}
});
Using Dropzone.js, I need to detect the dimesions of the image when added files and apply them to its parent .details div. The following code code works and return an alert with the added image width.
myDropzone.on("addedfile", function(file, xhr) {
var fr;
fr = new FileReader;
fr.onload = function() {
var img;
img = new Image;
img.onload = function() {
return alert(img.width);
};
return img.src = fr.result;
};
return fr.readAsDataURL(file);
});
The thing is that I have no idea how to assign the width to its parent .details element which set the preview width of the preview.
I try replacing the alert for this code but it doesn't do anything.
$(this).parent('.details').css('height',img.height);
I'm a bit lost in how to relate the value inside the onload function to applying it to its parent class.
With the latest version of dropzone you don't have to write this code yourself.
Simply read the file.width and file.height properties that are set on the file object when the thumbnail is generated.
The problem, why your CSS doesn't affect the element, is because you didn't specify the unit, px in this case. So your code can be:
myDropzone.on("thumbnail", function(file) {
$(this.element).parent('.details').css('height', file.height + 'px');
});