HTML5 Drag and Drop only images - javascript

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>

Related

How to draw a dragged and droppped image on to a canvas

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>

all image gets appended to last container div in multiple upload

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);
}

Uploading image and displaying it small with javascript

So, I've got this working javascript and it loads an image that a user uploads to the HTML on the screen displaying it.
But, it displays the image without a max height or width so it moves buttons on the page to where they can't be seen or pressed. This includes the submit button if the image uploaded is big enough.
So, is there some way to make the 'uploaded' image display really small: like max 30px in height?
$(function(){
$('#user_avatar').change(function(e){
var files = event.target.files;
var image = files[0];
for (var i = files.length - 1; i >= 0; i--) {
var reader = new FileReader();
var file = files[i];
reader.onload = function(file) {
var img = new Image();
img.src = file.target.result;
$('#inputpic').attr('src', file.target.result);
}
reader.readAsDataURL(image);
};
});
});
I have tried adding:
theimage = getElementById('inputpic')
theimage.style.height='10px';
But this had no effect.
EDIT 1
html.slim that the JS talks to:
= image_tag('temp.png', id: "inputpic", class: 'tiny_image_display')
SCSS that I made:
.tiny-image-display {
max-height: 30px;
}
You can set this in CSS very easily:
#inputpic {
max-height: 30px;
}
$(function(){
$('#user_avatar').change(function(e){
var files = event.target.files;
var image = files[0];
for (var i = files.length - 1; i >= 0; i--) {
var reader = new FileReader();
var file = files[i];
reader.onload = function(file) {
var img = new Image();
img.src = file.target.result;
img.height = "30";
$('#inputpic').attr('src', file.target.result);
}
reader.readAsDataURL(image);
};
});
});

How to get image width and height using JavaScript before upload?

How to get image width and height using Javascript before upload? I tried to test my code, but it does not work. How can I achieve this?
https://jsfiddle.net/r78qkjba/1/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<input name="offer_image_1" onchange="check_thumbnail_image_format_fn()" type="file" id="offer_image_1" />
<script>
function check_thumbnail_image_format_fn() {
var offer_image_1_data = document.getElementById("offer_image_1");
var offer_image_1_data_file = offer_image_1_data.files[0];
var offer_image_1_data_file_width = offer_image_1_data_file.width;
var offer_image_1_data_file_height = offer_image_1_data_file.height;
alert(offer_image_1_data_file_width);
alert(offer_image_1_data_file_height);
};
</script>
HTML5 and the File API
Here's the uncommented working code snippet example:
window.URL = window.URL || window.webkitURL;
var elBrowse = document.getElementById("browse"),
elPreview = document.getElementById("preview"),
useBlob = false && window.URL; // `true` to use Blob instead of Data-URL
function readImage (file) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.addEventListener("load", function () {
var imageInfo = file.name +' '+
image.width +'×'+
image.height +' '+
file.type +' '+
Math.round(file.size/1024) +'KB';
elPreview.appendChild( this );
elPreview.insertAdjacentHTML("beforeend", imageInfo +'<br>');
});
image.src = useBlob ? window.URL.createObjectURL(file) : reader.result;
if (useBlob) {
window.URL.revokeObjectURL(file); // Free memory
}
});
reader.readAsDataURL(file);
}
elBrowse.addEventListener("change", function() {
var files = this.files;
var errors = "";
if (!files) {
errors += "File upload not supported by your browser.";
}
if (files && files[0]) {
for(var i=0; i<files.length; i++) {
var file = files[i];
if ( (/\.(png|jpeg|jpg|gif)$/i).test(file.name) ) {
readImage( file );
} else {
errors += file.name +" Unsupported Image extension\n";
}
}
}
if (errors) {
alert(errors);
}
});
#preview img{height:100px;}
<input id="browse" type="file" multiple />
<div id="preview"></div>
Using an input and a div for the images preview area
<input id="browse" type="file" multiple>
<div id="preview"></div>
let's also use a CSS to keep the resulting images a reasonable height:
#preview img{ height:100px; }
JavaScript:
window.URL = window.URL || window.webkitURL;
var elBrowse = document.getElementById("browse"),
elPreview = document.getElementById("preview"),
useBlob = false && window.URL; // `true` to use Blob instead of Data-URL
// 2.
function readImage (file) {
// 2.1
// Create a new FileReader instance
// https://developer.mozilla.org/en/docs/Web/API/FileReader
var reader = new FileReader();
// 2.3
// Once a file is successfully readed:
reader.addEventListener("load", function () {
// At this point `reader.result` contains already the Base64 Data-URL
// and we've could immediately show an image using
// `elPreview.insertAdjacentHTML("beforeend", "<img src='"+ reader.result +"'>");`
// But we want to get that image's width and height px values!
// Since the File Object does not hold the size of an image
// we need to create a new image and assign it's src, so when
// the image is loaded we can calculate it's width and height:
var image = new Image();
image.addEventListener("load", function () {
// Concatenate our HTML image info
var imageInfo = file.name +' '+ // get the value of `name` from the `file` Obj
image.width +'×'+ // But get the width from our `image`
image.height +' '+
file.type +' '+
Math.round(file.size/1024) +'KB';
// Finally append our created image and the HTML info string to our `#preview`
elPreview.appendChild( this );
elPreview.insertAdjacentHTML("beforeend", imageInfo +'<br>');
});
image.src = useBlob ? window.URL.createObjectURL(file) : reader.result;
// If we set the variable `useBlob` to true:
// (Data-URLs can end up being really large
// `src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAA...........etc`
// Blobs are usually faster and the image src will hold a shorter blob name
// src="blob:http%3A//example.com/2a303acf-c34c-4d0a-85d4-2136eef7d723"
if (useBlob) {
// Free some memory for optimal performance
window.URL.revokeObjectURL(file);
}
});
// 2.2
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
reader.readAsDataURL(file);
}
// 1.
// Once the user selects all the files to upload
// that will trigger a `change` event on the `#browse` input
elBrowse.addEventListener("change", function() {
// Let's store the FileList Array into a variable:
// https://developer.mozilla.org/en-US/docs/Web/API/FileList
var files = this.files;
// Let's create an empty `errors` String to collect eventual errors into:
var errors = "";
if (!files) {
errors += "File upload not supported by your browser.";
}
// Check for `files` (FileList) support and if contains at least one file:
if (files && files[0]) {
// Iterate over every File object in the FileList array
for(var i=0; i<files.length; i++) {
// Let's refer to the current File as a `file` variable
// https://developer.mozilla.org/en-US/docs/Web/API/File
var file = files[i];
// Test the `file.name` for a valid image extension:
// (pipe `|` delimit more image extensions)
// The regex can also be expressed like: /\.(png|jpe?g|gif)$/i
if ( (/\.(png|jpeg|jpg|gif)$/i).test(file.name) ) {
// SUCCESS! It's an image!
// Send our image `file` to our `readImage` function!
readImage( file );
} else {
errors += file.name +" Unsupported Image extension\n";
}
}
}
// Notify the user for any errors (i.e: try uploading a .txt file)
if (errors) {
alert(errors);
}
});
Hope below code will help you.
var _URL = window.URL || window.webkitURL;
$("#offer_image_1").change(function (e) {
var file, img;
if ((file = this.files[0])) {
img = new Image();
img.onload = function () {
alert(this.width + " " + this.height);
};
img.src = _URL.createObjectURL(file);
}
});
You don't need to add onchange event at the input node.
This code is taken from
Check image width and height before upload with Javascript

Canvas image parsing orientation not in right sequence

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!

Categories

Resources