I am working on a multiple file upload system.File upload works fine.Problem arises when i've decided to show a preview div before file reading complete.For this purpose i create a container div inside for loop and tried to insert image in that container.Problem is that file is only gets appended to last container div.
function handleDragOver(event)
{
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
document.getElementById('drop_zone').innerHTML="";
}
function handleDragLeave()
{
document.getElementById('drop_zone').style.background = 'white';
}
function handleFileSelect(event)
{
event.stopPropagation();
event.preventDefault();
var files = event.dataTransfer.files;
for(var i=0,file;file=files[i];i++){
if(i>=files.length){
break;
}
var reader = new FileReader();
var container = document.createElement('div');
reader.onloadstart = function (){
container.setAttribute('style','background:gray;padding:5px;width:100px;height:100px;margin:10px;float:left;border:1px solid gray;');
document.getElementById('drop_zone').appendChild(container);
};
reader.onload = (function(myfile){
return function(event){
var img = new Image();
img.src = event.target.result;
img.width = 100;
img.height = 100;
container.style.background = 'white';
container.appendChild(img);
}
})(file);
reader.readAsDataURL(file);
}
}
function handleFileUpload()
{
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('dragleave', handleDragLeave, false);
dropZone.addEventListener('drop', handleFileSelect, false);
}
handleFileUpload();
<div id="drop_zone" style="width:95%;border:4px dotted gray;float:left;min-height:100px;text-align:center;line-height:100px;color:gray;font-size:25px;">
Drop files here
</div>
Use a closure within for loop to reference current file
for (var i = 0, file; file = files[i]; i++) {
(function(file) {
// do stuff with `file` here
// `file` is current `File` object
})(file);
}
change for loop in handleFileSelect(event)
for(var i=0,file;file=files[i];i++){
if(i>=files.length){
break;
}
var reader = new FileReader();
reader.onloadstart = function (){
/*
container.setAttribute('style','background:gray;padding:5px;width:100px;height:100px;margin:10px;float:left;border:1px solid gray;');
document.getElementById('drop_zone').appendChild(container);
*/
};
reader.onload = (function(myfile){
return function(event){
var container = document.createElement('div');
container.setAttribute('style','background:gray;padding:5px;width:100px;height:100px;margin:10px;float:left;border:1px solid gray;');
document.getElementById('drop_zone').appendChild(container);
var img = new Image();
img.src = event.target.result;
img.width = 100;
img.height = 100;
container.style.background = 'white';
container.appendChild(img);
}
})(file);
reader.readAsDataURL(file);
}
Related
I drag and drop images on to a canvas using below code . Can someone please tell me how to draw it on a canvas? Thanks in advance.Earlier my canvas used to be a div and I used to append img to that div and it worked.But now I want it to be drawn to a canvas.
function dropb(ev) {
ev.preventDefault();
const dt = ev.dataTransfer;
const files = dt.files;
handleFilesb(files);
}
function handleFilesb(files) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (!file.type.startsWith('image/')) {
continue
}
const img = document.createElement("img");
img.className = "my_image";
img.setAttribute("width", "300px");
img.setAttribute("height", "300px");
img.classList.add("obj");
img.file = file;
document.getElementById("area_c"); // canvas
var ctx = c.getContext("2d");
ctx.drawImage(img, 10, 10); // this line is not working
const reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
}
<div style="display:flex">
<canvas id ="area_c" style="width:300px;height:300px;border:3px solid black;z-index:1" ondrop="dropb(event)" ondragover="myfkb(event)" >
</canvas>
<div id ="area_c2" style="width:300px;height:300px;border:3px solid black;z-index:1" >
</div>
<div >
<input type="button" value="Crop"
onclick="crop()">
</div>
</div>
ctx.drawImage(img) comes before img.src... There is no way your image gets drawn.
You need to wait until it loads, and that will be only after the FileReader onload event fired, and even after the img's onload fires:
img.onload = e => {
ctx.drawImage(img, 10, 10);
};
const reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
But you don't need the FileReader here, use a blob URL instead:
img.onload = e => {
ctx.drawImage(img, 10, 10);
};
img.src = URL.createObjetURL(file);
const c = document.getElementById("area_c");
c.ondragover = e => {
e.preventDefault();
}
c.ondrop = dropb;
const ctx = c.getContext("2d");
function dropb(ev) {
ev.preventDefault();
const dt = ev.dataTransfer;
const files = dt.files;
handleFilesb(files);
}
function handleFilesb(files) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (!file.type.startsWith('image/')) {
continue
}
const img = document.createElement("img");
img.className = "my_image";
img.setAttribute("width", "300px");
img.setAttribute("height", "300px");
img.classList.add("obj");
img.file = file;
img.onload = e => {
ctx.drawImage(img, 10, 10);
};
img.src = URL.createObjectURL(file);
}
}
canvas {
border: 1px solid
}
<canvas id="area_c">
</canvas>
I was trying to use ocrad.js to convert an image to a string, but I didn't get the result string. I was also previewing the image, the problem is only in the image recognition.
This is my code:
function pr_image(event) {
var reader = new FileReader();
reader.onload = function() {
var output = document.getElementById('output_image');
output.src = reader.result;
}
reader.readAsDataURL(event.target.files[0]);
var stringletter = OCRAD(event.target.files[0]);
document.getElementById('letter').value = stringletter;
}
and this is the browser's capture:
unchanged value
no error message in console
I've tried to change the recognition code into this one function, but i get . as the image recognition's result:
function str_img(event) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
context.drawImage(this, 0, 0);
}
var imageData = context.getImageData(0, 0, 100, 100);
var stringletter = OCRAD(imageData);
document.getElementById('letter').value = stringletter;
}
I suspect that I failed at converting the input file as image data. What should I do? Any help is appreciated!
Solved:
I've changed my code into this by Chris G and it works! Thank you
function preview_image(event)
{
var reader = new FileReader();
var output = document.getElementById('output_image');
reader.onload = function()
{
output.src = reader.result;
}
reader.readAsDataURL(event.target.files[0]);
output.onload = function()
{
var stringletter = OCRAD(output);
document.getElementById('letter').value = stringletter;
}
}
i've image uploader which using canvas and trying to get orientation using load-image.all.min.js is fine. but when i choose multiple image orientation parsing function saving data not one by one.
which means if i choose 1 image. it transferring data to 'upload_canvas.php?ori='+ori with correct ori variable.
but when i choose multiple image to upload example 3 images (with orientation 1, 1, 8)
it passing data to server upload_canvas.php?ori=8, upload_canvas.php?ori=8, upload_canvas.php?ori=8. only last ori variable.
maybe orientation parsing function already looped before uploading image data to server one by one.
how to transfer image with correct orientation to server?
below my using code.
document.querySelector('form input[type=file]').addEventListener('change', function(event){
// Read files
var files = event.target.files;
var ori = 1;
// Iterate through files
for (var i = 0; i < files.length; i++) {
// Ensure it's an image
if (files[i].type.match(/image.*/)) {
//Get image orienatation
loadImage.parseMetaData(files[i], function (data) {
if (data.exif) {
ori = data.exif.get('Orientation');
console.log("ori: "+ori);
} else {ori = 1;}
});
// Load image
var reader = new FileReader();
reader.onload = function (readerEvent) {
var image = new Image();
image.onload = function (imageEvent) {
canvas.width = image.width;
canvas.height = image.height;
drawImageIOSFix(canvas.getContext('2d'),image, 0, 0, image.width, image.height, 0, 0, width, height);
// Upload image
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// Update progress
xhr.upload.addEventListener('progress', function(event) {
var percent = parseInt(event.loaded / event.total * 100);
progressElement.style.width = percent+'%';
}, false);
// File uploaded / failed
xhr.onreadystatechange = function(event) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
//some code
} else {
imageElement.parentNode.removeChild(imageElement);
}
}
}
xhr.open('post', 'upload_canvas.php?t=' + Math.random()+'&ori='+ori, true);
xhr.send(canvas.toDataURL('image/jpeg'));
}
}
image.src = readerEvent.target.result;
}
reader.readAsDataURL(files[i]);
}
}
// Clear files
event.target.value = '';});
Your variable ori is a global variable, that is shared between all images. The code in the .onload functions aren't run immediately, but only after your for() loop has gone through all the images. At this point ori will contain the orientation of the last image.
To fix, move the variable and parseMetaData into the reader.onload function.
...
var reader = new FileReader();
reader.onload = function (readerEvent) {
var ori;
loadImage.parseMetaData(files[i], ...)
var image = new Image();
image.onload = function (imageEvent) {
...
Warning: Not tested!
I want to put next to each thumbnail a little cross to be able to remove them one by one. I am able to remove image by click on it but I would like to have seperate button "x" to remove it.
fileInput.addEventListener("change", function (e) {
var filesVAR = this.files;
showThumbnail(filesVAR);
}, false);
function showThumbnail(files) {
var file = files[0]
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
image.setAttribute('class', 'imgKLIK5');
thumbnail.appendChild(image)
var reader = new FileReader()
reader.onload = (function (aImg) {
return function (e) {
aImg.src = e.target.result;
};
}(image))
var ret = reader.readAsDataURL(file);
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
image.onload = function () {
ctx.drawImage(image, 100, 100);
}
}
});
Here is my code in JFIDDLE
Can You help me out, please?
see this example with close button:http://jsfiddle.net/kevalbhatt18/r0taz01L/1/
$('div').on('click', '.closeDiv', function () {
$(this).prev().remove();
$(this).remove();
$('#upload-file').val("");
});
And I made this changes in your showThumbnail function
function showThumbnail(files) {
var file = files[0]
var thumbnail = document.getElementById("thumbnail");
var pDiv = document.createElement("div");
var image = document.createElement("img");
var div = document.createElement("div");
pDiv.setAttribute('class', 'pDiv');
thumbnail.appendChild(pDiv);
image.setAttribute('class', 'imgKLIK5');
pDiv.appendChild(image)
div.innerHTML = "X";
div.setAttribute('class', 'closeDiv');
pDiv.appendChild(div).......
...................
Just add new button element on each preview with following style attributes,
float:right;
position:relative;
you can remove the img from div thumbnail on click the "x" button, check this fiddle
What i'm trying to do is : if all the dragged files was images drop them, but if there was other file exstensions don't drop them, but drop the images only.
Here's my try :
HTML :
<div id="dropzone"></div>
Javascript :
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function (e) {
e.preventDefault();
e.stopPropagation();
var files = e.dataTransfer.files;
for(x = 0; x < files.length; x = x + 1){
if(files[x].type.split("/")[0] == 'image') {
console.log(files[x].name + "is image");
}else {
console.log(files[x].name + "is not image");
}
}
}
i need to loop through the files that i dragged and if the file was image do something otherwise do something else, for example
file.jpeg is image
file.txt is not image
But using my code if i dragged other file extension with the image it's not dropping the image, it's skipping both files.
The point is : Dropping only images.
You could use the FileReader and test the file type for an image like this:
// don't try to process non-images
var imageType = /image.*/;
if (file.type.match(imageType)) {
// it's an image, process it
}
Here's example code and a Demo:
// dropzone event handlers
var dropzone;
dropzone = document.getElementById("dropzone");
dropzone.addEventListener("dragenter", dragenter, false);
dropzone.addEventListener("dragover", dragover, false);
dropzone.addEventListener("drop", drop, false);
//
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
}
//
function dragover(e) {
e.stopPropagation();
e.preventDefault();
}
//
function drop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
handleFiles(files);
}
//
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
// get the next file that the user selected
var file = files[i];
var imageType = /image.*/;
// don't try to process non-images
if (!file.type.match(imageType)) {
continue;
}
// a seed img element for the FileReader
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
// get an image file from the user
// this uses drag/drop, but you could substitute file-browsing
var reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
aImg.onload = function() {
// draw the aImg onto the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = aImg.width;
canvas.height = aImg.height;
ctx.drawImage(aImg, 0, 0);
// make the jpeg image
var newImg = new Image();
newImg.onload = function() {
newImg.id = "newest";
document.body.appendChild(newImg);
}
newImg.src = canvas.toDataURL('image/jpeg');
}
// e.target.result is a dataURL for the image
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
} // end for
} // end handleFiles
body {
background-color: ivory;
}
canvas {
border: 1px solid red;
}
#dropzone {
border: 1px solid blue;
width: 300px;
height: 300px;
}
<h4>Drag file(s) from desktop to blue dropzone.<br>Only image files will be processed.</h4>
<div id="dropzone"></div>
<div id="preview"></div>