Adding thumbnails and remove button to a form file input - javascript

I am using Rails and I've got a form with a bunch of fields and one of those is image uploading. For now it's just a typical button with multiple option on and it does almost everything I need, but I'd like images' previews (thumbnails) to appear when a user selects images and I'd like to have a "remove" button on these thumbnails in case user decides to remove some image from the collection.
I've tried to use dropzone.js but I dont wanna send form as JSON and I want files to be a part of file input field.
Also I tried to use Jquery File Upload, but I got too confused in all that and so I've tried to use just FileReader API which is what I needed, but I couldnt manage to add remove buttons... Also I wouldnt like to use ajax for that, I think it can be done without it somehow and I dont necesserily need a drag and drop functionality.
Anyway, I think it should be an easy thing to do but I cant find any appropriate tutorials or something for that, so I hope to get some link to a tutorial or just some hint that'll help me to solve the issue.
Thank you.

You can use canvas and FileReader API. Something like this:
$('#yourFileInputField').bind('change', function(e) {
var reader;
reader = new FileReader();
reader.onload = function(event) {
var img;
img = new Image();
img.onload = function() {
var canvas, context;
canvas = $('#canvasId')[0];
context = canvas.getContext('2d');
context.drawImage(img, 0, 0, canvas.width, canvas.height);
};
};
reader.readAsDataURL(e.target.files[0]);
});
When you click on remove just clear canvas and file input field.

Related

Delete exif data (xmp) from image in React

I have spent my entire day trying to delete EXIF data from images with React. I want to do this for try to solve another problem, when user uploads an image with XMP data, apparently AWS WAF blocks it (I didn't have problems with another kind of data, I dind't tried everything tho, but I used an image with camera information and blabla and it worked just fine. Plus, I deleted XMP data from problematic images with a software, and WAF didn't blocked it anymore). So, I want to delete XMP data (author, creator tool, etc.) before send it to server.
I'm using react-dropzone for upload the images, and today I tried different libraries for achieve this, without success. With exifr and exif-js I can see all the EXIF information (including XMP) and specificcaly the data that is causing the error in the upload, but I didn't find a way to remove that from the picture. On the other hand, I used piexifjs and worked fine for delete information, but I couldn't find XMP data!! Just gps, EXIF with camera and picture settings, plus a couple of thing not of my interest. What can I do? I'm able to see this information with exif-js and exifr, but I just can delete things with pixiefjs in which I can't see xmp data.
I do not provide code because it is not an error as such, I want library recommendations or, if exists, a way to configure piexifjs for find this kind of data. exif-js and exifr are for reading, not for removing.
Thanks a lot.
Here would be a sample code of mine:
With a right on the image you should be able to download the image and there should be no exif data included. But I am unsure if there is a better way to do that.
document.getElementById('upload').onchange = function() {
const img = new Image();
img.src = URL.createObjectURL(this.files[0]);
img.onload = function() {
//canvas
const canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(this, 0,0);
//image in html
newImg = document.getElementById('img');
newImg.src = canvas.toDataURL();
newImg.style.width = this.width;
newImg.style.height = this.height;
};
img.onerror = function() {console.error("The file is not an image")};
};
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="file" id="upload">
<img id="img"></img>
<script src="script.js"></script>
</body>
</html>
I'm unsure if it couldn't be simpler, but you could create a canvas with the size of the image, load the image into it, and write the image data from the canvas to a new image file.

How to attach a file to html 'file' element for upload with jquery/js?

Here is the html element we are trying to attach a file to:
<input id="uploaded_file_file_for_upload" class="file optional" type="file" name="uploaded_file[file_for_upload]">
User already selects a file for the element above. What we need to do is to remove the current file selection and attach a new file to it. The new file is an image file and is saved in a canvas element. Here is the js code for new file:
function resize(image, width, height) {
var mainCanvas = document.createElement("canvas");
mainCanvas.width = width;
mainCanvas.height = height;
var ctx = mainCanvas.getContext("2d");
alert(width + ' resize to ' + height);
ctx.drawImage(image, 0, 0, width, height);
.....(remove current and attach the new file to the elelment#uploaded_file_file_for_upload)
};
We tried the following to attach and it did not work:
$('#uploaded_file_file_for_upload').attr('src', mainCanvas.toDataURL("image/jpeg"));
The problem may be that it is not an image element. What's the right way to remove and attach a file type?
The short answer is you can't. The only way to upload a file is to ship the file selected by the user, with no change.
The only way to do exactly what you are trying to do here is using :
a native app
a hybrid app with native plugin
via a browser plugin (flash, chrome app...)
Unless, the browser security policy will block you.
Two workarounds could be:
send the original file and resize it server side (php library, nodejs...)
or resize the image as you want, then uploading the base64 encoded image data of the edited image via a POST ajax request to your server, and then write it to a file server side.

Download a Html5 canvas element as an image with the file extension with Javascript

I would like to be able to download a Html5 canvas element as an image with the file extension with Javascript.
The CanvasToImage library does not seem to be able to achieve this.
Here is my code so far which you can see at this JsFiddle.
<div id="canvas_container">
</div>
<p>
create
download
</p>
$("#create_image").click(function() {
var cnvs = createSmileyOnCanvas();
$('#canvas_container').append(cnvs);
});
$("#download_image").click(function() {
var img = $('#smiley_canvas').toDataURL("image/png");
var uriContent = "data:application/octet-stream," + encodeURIComponent(img);
window.open(uriContent, 'download smiley image');
});
function createSmileyOnCanvas() {
var canvas = document.createElement('canvas');
canvas.id = 'smiley_canvas';
var ctx = canvas.getContext('2d');
// Draw shapes
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false); // Mouth
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true); // Left eye
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true); // Right eye
ctx.stroke();
return canvas;
}
This seems to work for me:
<a id="downloadImgLink" onclick="$('#downloadImgLink').attr('href', canvas.toDataURL());" download="MyImage.png" href="#" target="_blank">Download Drawing</a>
In order to force/suggest a file name in the browser's download dialog, you would need to send the Content-Disposition: attachment; filename=foobar.png header.
This is not possible to do via window.open, so you're out of luck unless there are some browser-specific hacks for this.
If you really need the filename, you could try using the new download attribute in a, <a href="put stuff here" download="filename here">. It isn't very widely supported yet though.
Another alternative would be to first submit the data to the server using ajax, then redirect the browser to some server-side script which would then serve the data with the correct header.
Hi i have created a jquery plugin which will let you do the same task with ease but it also make use of php to download the image. let me explain how it works
Plugin has 2 sub function that you can call independently to add image to the canvas and the other one is to download the current image lying on the canvas.
Add image to the canvas
For this you need to pass the id of the canvas element and the path of the image you want to add
download image from the canvas
For this you need to pass the id of the canvas element
$('body').CanvasToPhp.upload({
canvasId: "canvas", // passing the canvasId
image: "455.jpg" // passing the image path
});
// downloading file
$('#download').click(function(){
$('body').CanvasToPhp.download({
canvasId: "canvas" // passing the canvas id
}); //
});
First you need to download the plugin file which you can find here http://www.thetutlage.com/post=TUT213
I have also created a little demo http://thetutlage.com/demo/canvasImageDownload

What is this simple javascript doing

I am reading a tutorial and keep getting stuck on the first line of code, I know "new" in php is to make an object, but this tutorial has nothing to do with that. please help
var img = new Image();
the tutorial is here:
http://jqueryfordesigners.com/image-loading/
Ok, I found the W3 definition of the predefined javascript object Image(): http://www.w3schools.com/jsref/dom_obj_image.asp
Actually, in JavaScript new is used when making objects too, just like PHP.
As you can guess, therefore, that line of code simply instantiates an Image object and assigns it to the img variable.
this has nothing to do with jQuery.
Image is a native JavaScript object which corresponds to a HTML image object.
what the line means, is
"create a new variable 'img' and set it to a newly initialised Image object"
you can preload an image with
var img = new Image();
they preload the image images/headshot.jpg
then they wait until it has been loaded
then thay hide the loading image and fade in the image
It's make an html form for you.
for detail read this http://www.devguru.com/technologies/ecmascript/quickref/image.html
Hope this might help you a lot.
or you want to know it create
var img = new Image();
and not use?
$(img)
// once the image has loaded, execute this code
.load(function () {
// set the image hidden by default
$(this).hide();
// with the holding div #loader, apply:
$('#loader')
// remove the loading class (so no background spinner),
.removeClass('loading')
// then insert our image
.append(this);
// fade our image in to create a nice effect
$(this).fadeIn();
})
// if there was an error loading the image, react accordingly
.error(function () {
// notify the user that the image could not be loaded
})
// *finally*, set the src attribute of the new image to our image
.attr('src', 'images/headshot.jpg');
});
The 'this' keyword is represent for img variable

How to load an image asynchronously?

I'm loading an image onto a texture map with GLGE (sorta like webGl). However for the sake of loading speed I'm loading a low resolution image first (which would be quicker) and then want to change the src to the high resolution image once the large image is loaded. This is what I'm doing now
var texture = new GLGE.texture();
function updateTexture(){
var image=new Image();
image.src = "models/testLargeMap_map0.jpg"; // load image
image.onload = function(){
texture.image("models/testLargeMap_map0.jpg"); // supposedly swap image on load (not working as I thought)
}
}
However, when during this period of changing the src, the model and all its functions freeze. How do I make it load the image asynchronously and on load swap it to the higher texture for a smooth instantaneous texture change?
You can set an image.onload event handler like this:
var big_image = new Image();
big_image.onload = function () {
texture.image("models/testLargeMap_map0.jpg");
}
big_image.src = "models/testLargeMap_map0.jpg";
(Note that I set the onload handler first, then set the src attribute. If I do it the other way around, it fails in IE).
This will preload the image before calling texture.image. I don't know anything about this library though, so I can't be certain it will use the pre-loaded image.
The image.src will be requesting the image from the server and it will initiate the onload event, and again u are requesting the image to be swapped so it is getting freezed. Why do you need this approach. You can have better way of doing this like, allow the low resolution image to be loaded first then assign the onmouseover or onclick event for the image on that time u can show a popup like shown on google images and then in it just display the high resolution images. On that time u will be requesting a single image the process will be quicker.
Hope this helps you
I'm not familiar with "GLGE" but it looks like the problem is that the method .image() loads the image again (kind regardless if that happens in the load event handler for the same image).
So unless you can set the image reference directly, like
texture = this; // within the load handler
there is no way to accomplish it with this library.

Categories