I have create upload file , but I have stack when I want to validation that content is image or not, because if validate extension only we can manipulate with fake content and valid extension.
is there function similar getimagesize() php in javascript?
In some of the more modern browsers you can load an image into a canvas context (this doesn't actually have to be displayed on the page) and get the dimensions from that.
I did something like this in a CMS I built to allow the image to be scanned for certain colours without it having to be uploaded to a server first:
$('section.content form input[name=image]').change(function(){
file = this.files[0];
if(file.type.match(/image.*/))
{
var img = document.createElement('img');
// add this into an onload, as it takes time (albeit very little) to load the image into the DOM object
img.onload = function(){
canv = document.getElementById('product_image');
if(!canv || !canv.getContext)
return; // problem getting the canvas element
// get the canvas context that we'll be using and the width of the canvas & image
var ctx = canv.getContext('2d');
var width = img.width;
var height = img.height;
};
// put the file into the img object, triggering the img onload handler above
var reader = new FileReader();
reader.onload = function(e) {img.src = e.target.result};
reader.readAsDataURL(file);
}
});
Related
Basically, I use a Javascript Library which has this code under a function:
var img = new Image(); // Create new img element
img.src = 'URL/myImage.png'; // Set source path
It will send multiple HTTP GET requests to server (in Firefox's Developer Console > Network, their type is 'img' under 'Cause' column).
How can I detect the event (image starts loading and image loaded completely) from the code above in my index.html using the javascript library (I cannot change the library)?
This can be done by listening to the onloadstart and onload events respectively.
function ready() {
console.log("picture loaded");
}
function started() {
console.log("loading");
}
var img = new Image();
img.onload = ready;
img.onloadstart = started;
img.src = "https://picsum.photos/200/300";
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 read an image using the FileReader API, then I store the image as a blob in Indexeddb for later synchronization with a server. Until then I want to display a thumbnail of the image. It seems suboptimal to add the image ie. to a canvas element in full resolution and then resize it. It seems a better solution would be to resize it before adding it.
After synchronization I want to delete the full resolution image and only show the thumbnail. (My main concern is storage limits in a web app, on a mobile device)
Is it possible? and how?
Do not worry about adding extra stuff to the DOM, just do not do anything that will render it.
assuming you start with something along the lines of -
var reader = new FileReader();
reader.onload = function (e)
{
var img = new Image ;
img.src = e.target.result;
img.onload = function ()
then inside this onload function you can...
var canvas = document.createElement("canvas");
var context = canvas.getContext ("2d");
//draw it at any resolution you want
context.drawImage (this, 0, 0, width, height);
// read it back from the canvas, compressing if you want to
var saveData = canvas.toDataURL("image/jpeg",0.7);
// and save it where you want
// delete the canvas element unless you want to keep doing this regularly
Adding regular png images was no problem with jsPDF, but now i send a generated image from my server and the browser console displays this error when rendering the PDF file:
Incomplete or corrupt PNG file
obviously the image is not incomplete or corrupt because i can see the response from the server and the image is fine.
Also to avoid render the pdf file before the image is ready i make a check to a that holds the image value variable if is undefined/null.
the format of my image is
var image = "data:image/png;base64,iVBORw0KGgoAAAANSUh...etc";
What could be the problem?
Edit: i changed the format of the image to jpg and this error shows
Supplied data is not a JPEG
if i use this library jspdf.plugin.addimage.js the images are rendered correctly but not the png images.
edit: 2 i made a solution modifying the jspdf.plugin.addimage.js file function addImage, i just changed the name of the function and added those generated images to pdf with that function, since the version of jspdf.min.js has the same name for the same function with this way it won't override the function i can use the one that works with normal images and the ones generated by the server.
This type of error occurs because the image has not finished loading when you send to jsPdf, use onLoad event to check the image loaded completely. for Example -
/* where src = full image url
callback = is callback function
outputFormat = image output format */
function toDataUrl(src, callback, outputFormat) {
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function () {
/*image completely converted to base64string */
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
/* call back function */
callback(dataURL);
};
img.src = src;
if (img.complete || img.complete === undefined) {
img.src = appConfig.config.dummyImage;
img.src = src;
}
}
function callbackBase64(base64Img)
{
/*base64Img contains full base64string of image */
console.log(base64Img);
}
call above function and get base64string of image -
toDataUrl('http://example1.com/image1.jpg', callbackBase64(base64Img), "image/png");
I want to avoid uploading big/heavy image files.
I prefer HTML5 FileAPI library for this job.
All other functionality is added (upload, re-order, etc.), so I only need the image-resize function.
CASE:
On the page there is an input for multiple files.
On input change event (when adding files), resize the entered images/files and append them to FormData(), then send the FormData() to PHP script via ajax.
EXAMPLE:
$('input').on('change',function(){
var formData = resizeImages(this.files[0]);
uploadResizedImages(formData);
});
function resizeImages(files){
formData = new FormData();
//For each image, resize it and append to formData
//resize file part missing....
formData.append('files[]',this);//Appending to formData (this = currently iterated file)
return formData;//Return the formData with resized images
}
Anyone?
Thanks
In my experience you cannot manipulate the image on the client side then upload the manipulated image in tact via a file input in a form.
The way I have done what you are trying to do in the past involves a few steps.
Select image using a file input
Read the file as a dataURL
Use canvas to manipulate the image as needed
Export the new image as a dataUrl
Use ajax to upload the image to the server as a dataURL
Use server side functions to convert the dataUrl to an image and store
https://jsfiddle.net/0hmhumL1/
function resizeInCanvas(img){
///////// 3-3 manipulate image
var perferedWidth = 2700;
var ratio = perferedWidth / img.width;
var canvas = $("<canvas>")[0];
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0,0,canvas.width, canvas.height);
//////////4. export as dataUrl
return canvas.toDataURL();
}
When uploading as a dataUrl you increase the size (bandwidth required) of the manipulated image by about 20% so you may not see the savings you are looking for unless you are changing the image size considerably.