How to restrict user to upload image in ink file picker? - javascript

I am using ink file picker to pick single iamge.
I want to restrict user to upload image with width 100 and height 300.
If image is not in proper size then send error message.
How to restrict user?

you can check image size using FileReader() and jquery
function readImage(file) {
var reader = new FileReader();
var image = new Image();
reader.readAsDataURL(file);
reader.onload = function(_file) {
image.src = _file.target.result; // url.createObjectURL(file);
image.onload = function() {
var w = this.width,
h = this.height,
t = file.type, // ext only: // file.type.split('/')[1],
n = file.name,
s = ~~(file.size/1024) +'KB';
if(w!=100 || h!=100){
alert("invalid height or width");
}
$('#uploadPreview').append('<img src="'+ this.src +'"> '+w+'x'+h+' '+s+' '+t+' '+n+'<br>');
};
image.onerror= function() {
alert('Invalid file type: '+ file.type);
};
};
}
$("#choose").change(function (e) {
if(this.disabled) return alert('File upload not supported!');
var F = this.files;
if(F && F[0]) for(var i=0; i<F.length; i++) readImage( F[i] );
});
HTML
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<meta charset=utf-8 />
<title>Multiple image upload with preview by Roko C.B.</title>
</head>
<body>
<input type="file" id="choose" multiple="multiple" />
<br>
<div id="uploadPreview"></div>
JS BIN example JSBIN

Related

Resize image in the client side before upload

Is there any client side script can resize automatically the image uploaded in the input file by the user, and replace automatically the old image by the new image resized in the same input ..I want to do this to send this image to my php model after.. thanks in advance for your help.
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
</head>
<body>
<form action="model.php" method="post" enctype="multipart/form-data">
<input type="file" name="image"/>
<input type="submit" name="do" value="submit"/>
</form>
</body>
</html>
<?php
$target_dir = "folder/";
$filename = $_FILES["image"]["name"];
$basename = basename($_FILES["image"]["name"]);
$target_file = $target_dir .$basename;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$tmp = $_FILES["image"]["tmp_name"];
if(move_uploaded_file($tmp,$target_file))
{
echo'done!';
}
?>
This is how i would have solved it...
// Used for creating a new FileList in a round-about way
function FileListItem(a) {
a = [].slice.call(Array.isArray(a) ? a : arguments)
for (var c, b = c = a.length, d = !0; b-- && d;) d = a[b] instanceof File
if (!d) throw new TypeError("expected argument to FileList is File or array of File objects")
for (b = (new ClipboardEvent("")).clipboardData || new DataTransfer; c--;) b.items.add(a[c])
return b.files
}
fileInput.onchange = async function change() {
const maxWidth = 320
const maxHeight = 240
const result = []
for (const file of this.files) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
const img = await file.image()
// native alternetive way (don't take care of exif rotation)
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap
// const img = await createImageBitmap(file)
// calculate new size
const ratio = Math.min(maxWidth / img.width, maxHeight / img.height)
const width = img.width * ratio + .5 | 0
const height = img.height * ratio + .5 | 0
// resize the canvas to the new dimensions
canvas.width = width
canvas.height = height
// scale & draw the image onto the canvas
ctx.drawImage(img, 0, 0, width, height)
// just to preview
document.body.appendChild(canvas)
// Get the binary (aka blob)
const blob = await new Promise(rs => canvas.toBlob(rs, 1))
const resizedFile = new File([blob], file.name, file)
result.push(resizedFile)
}
const fileList = new FileListItem(result)
// temporary remove event listener since
// assigning a new filelist to the input
// will trigger a new change event...
fileInput.onchange = null
fileInput.files = fileList
fileInput.onchange = change
}
<!-- screw-filereader will take care of exif rotation for u -->
<script src="https://cdn.jsdelivr.net/npm/screw-filereader#1.4.3/index.min.js"></script>
<form action="https://httpbin.org/post" method="post" enctype="multipart/form-data">
<input type="file" id="fileInput" name="image" accept="image/*" />
<input type="submit" name="do" value="submit" />
</form>
PS. it won't resize in stackoverflow due to iframe being more sandboxed and secure, work in jsfiddle: https://jsfiddle.net/f2oungs3/3/
You could draw the image to a resized canvas via the FileReader API and then use canvas.toDataURL('image/png') to get the base64 image to send to the server.
Here is a simplified example of resizing an image to 320x240:
document.getElementById('example').addEventListener('change', function(e) {
var canvas = document.createElement('canvas')
var canvasContext = canvas.getContext('2d')
canvas.setAttribute("style", 'opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000;width:320px;height:240px;')
document.body.appendChild(canvas);
var img = new Image;
img.onload = function() {
canvasContext.drawImage(img, 0, 0, 320, 240);
var base64Image = canvas.toDataURL('image/png')
console.log(base64Image)
// Post to server
// sendImage(base64Image)
document.body.removeChild(canvas)
URL.revokeObjectURL(img.src)
}
img.src = URL.createObjectURL(e.target.files[0]);
})
function sendImage() {
var data = canvas.toDataURL('image/png');
var ajax = null;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax.open('POST', 'https://example/route', true);
ajax.setRequestHeader('Content-Type', 'application/octet-stream');
ajax.onreadystatechange = function() {
if (ajax.readyState === XMLHttpRequest.DONE) {
if (ajax.status === 200) {
// Success
} else {
// Fail
}
}
};
ajax.send(data);
}
<input id="example" type="file" />
And then on the server:
// or however you want to get the posted contents.
$png = isset($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS["HTTP_RAW_POST_DATA"] : file_get_contents("php://input");
if (strpos($png, 'data:image/png;base64,') === 0) {
$png = str_replace('data:image/png;base64,', '', $png);
$png = str_replace(' ', '+', $png);
$png = base64_decode($png);
}
file_put_contents($image_path, $png);
EDIT
The code now includes a way to upload the image to the server.
You could also use jQuery or the more modern fetch API to upload the image.
JsFiddle available here

Find width and height uploaded image in canvas HTML5.(With file reader)

I am using HTML5 and fabric js for uploading multiple image in canvas. Right now i am uploading multiple image in canvas. But i want to find uploaded image width and height. I have seen one link Check image width and height before upload with Javascript
In this link not using file reader. But in my case using file reader.
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change",function (e) {
var file = e.target.files[0];
var reader = new FileReader();
console.log("reader " + reader);
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({ width: 250, height: 200, angle: 0}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
canvas{
border: 1px solid black;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<div style="">
<canvas id="canvas" width="450" height="450"></canvas>
</div>
You can create an img tag and get the dimensions from it.
document.getElementById('file').addEventListener("change",function (e) {
var file = e.target.files[0];
var reader = new FileReader();
var output = document.getElementById('output');
reader.onload = function (f) {
var data = f.target.result;
var img = document.createElement('img');
img.src = data;
img.onload = function() {
output.innerHTML = 'width: ' + img.width + '\n' +
'height: ' + img.height;
};
};
reader.readAsDataURL(file);
});
<input type="file" id="file"/>
<pre id="output"></pre>
#jcubic is right about using an <img> tag, (while there would be some ways to get this info without it) but he is absolutely wrong in how he gets the image's dimensions.
.clientWidth and .clientHeight will return the computed width of the <img> element. You don't care about it, since what you are drawing on your canvas is the image contained in the <img>, not the <img> element itself.
What you need then is .width and .height properties or .naturalWidth and .naturalHeight.
document.getElementById('file').addEventListener("change",function (e) {
var file = e.target.files[0];
var reader = new FileReader();
var output = document.getElementById('output');
reader.onload = function () {
var data = this.result;
var img = new Image();
img.src = data;
img.onload = function() {
output.innerHTML = 'width: ' + img.width + '\n' +
'height: ' + img.height;
};
};
reader.readAsDataURL(file);
});
<input type="file" id="file"/>
<pre id="output"></pre>

Image upload preview javascript

I am trying to make a image preview before upload. But when i am trying to upload them, there are upload only the latest ones.
Example: Firstly i upload 3 images(and it appears 3 file selected), then i want to upload 4 more images. And my problem is that it appears 4 images selected(not 7 images selected) but in the image preview there are all of them.
I use python to upload them in the datastore and in the datastore there are only the latest images.
Javascript
//<![CDATA[
$(function(){
jQuery(function ($) {
var fileDiv = document.getElementById("upload");
var fileInput = document.getElementById("upload-image");
console.log(fileInput);
fileInput.addEventListener("change", function (e) {
var files = this.files
showThumbnail(files)
}, false)
function showThumbnail(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i]
var imageType = /image.*/
if (!file.type.match(imageType)) {
console.log("Not an Image");
continue;
}
var image = document.createElement("img");
// image.classList.add("")
var thumbnail = document.getElementById("thumbnail");
image.file = file;
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)
}
}
}
});
});
//]]>
Html
<div class="row">
<div class="large-12 medium-12">
<input type="file" name='file' id="upload-image" multiple></input>
<div id="thumbnail">
</div>
</div>
</div>
Python
imagesnumber=len(self.get_uploads('file'))
while imagesnumber!=0:
image = self.get_uploads('file')[0]
img = DateBase()
img.blob_key = image.key()
img.img_url = images.get_serving_url( image.key() )
img.put()
imagesnumber=imagesnumber-1

Get file size, image width and height before upload

How can I get the file size, image height and width before upload to my website, with jQuery or JavaScript?
Multiple images upload with info data preview
Using HTML5 and the File API
Example using URL API
The images sources will be a URL representing the Blob object
<img src="blob:null/026cceb9-edr4-4281-babb-b56cbf759a3d">
const EL_browse = document.getElementById('browse');
const EL_preview = document.getElementById('preview');
const readImage = file => {
if ( !(/^image\/(png|jpe?g|gif)$/).test(file.type) )
return EL_preview.insertAdjacentHTML('beforeend', `Unsupported format ${file.type}: ${file.name}<br>`);
const img = new Image();
img.addEventListener('load', () => {
EL_preview.appendChild(img);
EL_preview.insertAdjacentHTML('beforeend', `<div>${file.name} ${img.width}×${img.height} ${file.type} ${Math.round(file.size/1024)}KB<div>`);
window.URL.revokeObjectURL(img.src); // Free some memory
});
img.src = window.URL.createObjectURL(file);
}
EL_browse.addEventListener('change', ev => {
EL_preview.innerHTML = ''; // Remove old images and data
const files = ev.target.files;
if (!files || !files[0]) return alert('File upload not supported');
[...files].forEach( readImage );
});
#preview img { max-height: 100px; }
<input id="browse" type="file" multiple>
<div id="preview"></div>
Example using FileReader API
In case you need images sources as long Base64 encoded data strings
<img src="data:image/png;base64,iVBORw0KGg... ...lF/++TkSuQmCC=">
const EL_browse = document.getElementById('browse');
const EL_preview = document.getElementById('preview');
const readImage = file => {
if ( !(/^image\/(png|jpe?g|gif)$/).test(file.type) )
return EL_preview.insertAdjacentHTML('beforeend', `<div>Unsupported format ${file.type}: ${file.name}</div>`);
const reader = new FileReader();
reader.addEventListener('load', () => {
const img = new Image();
img.addEventListener('load', () => {
EL_preview.appendChild(img);
EL_preview.insertAdjacentHTML('beforeend', `<div>${file.name} ${img.width}×${img.height} ${file.type} ${Math.round(file.size/1024)}KB</div>`);
});
img.src = reader.result;
});
reader.readAsDataURL(file);
};
EL_browse.addEventListener('change', ev => {
EL_preview.innerHTML = ''; // Clear Preview
const files = ev.target.files;
if (!files || !files[0]) return alert('File upload not supported');
[...files].forEach( readImage );
});
#preview img { max-height: 100px; }
<input id="browse" type="file" multiple>
<div id="preview"></div>
Demo
Not sure if it is what you want, but just simple example:
var input = document.getElementById('input');
input.addEventListener("change", function() {
var file = this.files[0];
var img = new Image();
img.onload = function() {
var sizes = {
width: this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
console.log('onload: sizes', sizes);
console.log('onload: this', this);
}
var objectURL = URL.createObjectURL(file);
console.log('change: file', file);
console.log('change: objectURL', objectURL);
img.src = objectURL;
});
If you can use the jQuery validation plugin you can do it like so:
Html:
<input type="file" name="photo" id="photoInput" />
JavaScript:
$.validator.addMethod('imagedim', function(value, element, param) {
var _URL = window.URL;
var img;
if ((element = this.files[0])) {
img = new Image();
img.onload = function () {
console.log("Width:" + this.width + " Height: " + this.height);//this will give you image width and height and you can easily validate here....
return this.width >= param
};
img.src = _URL.createObjectURL(element);
}
});
The function is passed as ab onload function.
The code is taken from here
Here is a pure JavaScript example of picking an image file, displaying it, looping through the image properties, and then re-sizing the image from the canvas into an IMG tag and explicitly setting the re-sized image type to jpeg.
If you right click the top image, in the canvas tag, and choose Save File As, it will default to a PNG format. If you right click, and Save File as the lower image, it will default to a JPEG format. Any file over 400px in width is reduced to 400px in width, and a height proportional to the original file.
HTML
<form class='frmUpload'>
<input name="picOneUpload" type="file" accept="image/*" onchange="picUpload(this.files[0])" >
</form>
<canvas id="cnvsForFormat" width="400" height="266" style="border:1px solid #c3c3c3"></canvas>
<div id='allImgProperties' style="display:inline"></div>
<div id='imgTwoForJPG'></div>
SCRIPT
<script>
window.picUpload = function(frmData) {
console.log("picUpload ran: " + frmData);
var allObjtProperties = '';
for (objProprty in frmData) {
console.log(objProprty + " : " + frmData[objProprty]);
allObjtProperties = allObjtProperties + "<span>" + objProprty + ": " + frmData[objProprty] + ", </span>";
};
document.getElementById('allImgProperties').innerHTML = allObjtProperties;
var cnvs=document.getElementById("cnvsForFormat");
console.log("cnvs: " + cnvs);
var ctx=cnvs.getContext("2d");
var img = new Image;
img.src = URL.createObjectURL(frmData);
console.log('img: ' + img);
img.onload = function() {
var picWidth = this.width;
var picHeight = this.height;
var wdthHghtRatio = picHeight/picWidth;
console.log('wdthHghtRatio: ' + wdthHghtRatio);
if (Number(picWidth) > 400) {
var newHeight = Math.round(Number(400) * wdthHghtRatio);
} else {
return false;
};
document.getElementById('cnvsForFormat').height = newHeight;
console.log('width: 400 h: ' + newHeight);
//You must change the width and height settings in order to decrease the image size, but
//it needs to be proportional to the original dimensions.
console.log('This is BEFORE the DRAW IMAGE');
ctx.drawImage(img,0,0, 400, newHeight);
console.log('THIS IS AFTER THE DRAW IMAGE!');
//Even if original image is jpeg, getting data out of the canvas will default to png if not specified
var canvasToDtaUrl = cnvs.toDataURL("image/jpeg");
//The type and size of the image in this new IMG tag will be JPEG, and possibly much smaller in size
document.getElementById('imgTwoForJPG').innerHTML = "<img src='" + canvasToDtaUrl + "'>";
};
};
</script>
Here is a jsFiddle:
jsFiddle Pick, display, get properties, and Re-size an image file
In jsFiddle, right clicking the top image, which is a canvas, won't give you the same save options as right clicking the bottom image in an IMG tag.
As far as I know there is not an easy way to do this since Javascript/JQuery does not have access to the local filesystem. There are some new features in html 5 that allows you to check certain meta data such as file size but I'm not sure if you can actually get the image dimensions.
Here is an article I found regarding the html 5 features, and a work around for IE that involves using an ActiveX control. http://jquerybyexample.blogspot.com/2012/03/how-to-check-file-size-before-uploading.html
So I started experimenting with the different things that FileReader API had to offer and could create an IMG tag with a DATA URL.
Drawback: It doesn't work on mobile phones, but it works fine on Google Chrome.
$('input').change(function() {
var fr = new FileReader;
fr.onload = function() {
var img = new Image;
img.onload = function() {
//I loaded the image and have complete control over all attributes, like width and src, which is the purpose of filereader.
$.ajax({url: img.src, async: false, success: function(result){
$("#result").html("READING IMAGE, PLEASE WAIT...")
$("#result").html("<img src='" + img.src + "' />");
console.log("Finished reading Image");
}});
};
img.src = fr.result;
};
fr.readAsDataURL(this.files[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" accept="image/*" capture="camera">
<div id='result'>Please choose a file to view it. <br/>(Tested successfully on Chrome - 100% SUCCESS RATE)</div>
(see this on a jsfiddle at http://jsfiddle.net/eD2Ez/530/)
(see the original jsfiddle that i added upon to at http://jsfiddle.net/eD2Ez/)
A working jQuery validate example:
$(function () {
$('input[type=file]').on('change', function() {
var $el = $(this);
var files = this.files;
var image = new Image();
image.onload = function() {
$el
.attr('data-upload-width', this.naturalWidth)
.attr('data-upload-height', this.naturalHeight);
}
image.src = URL.createObjectURL(files[0]);
});
jQuery.validator.unobtrusive.adapters.add('imageminwidth', ['imageminwidth'], function (options) {
var params = {
imageminwidth: options.params.imageminwidth.split(',')
};
options.rules['imageminwidth'] = params;
if (options.message) {
options.messages['imageminwidth'] = options.message;
}
});
jQuery.validator.addMethod("imageminwidth", function (value, element, param) {
var $el = $(element);
if(!element.files && element.files[0]) return true;
return parseInt($el.attr('data-upload-width')) >= parseInt(param["imageminwidth"][0]);
});
} (jQuery));

checking image size before upload

I noticed when uploading a profile pic to Twitter that its size is checked before upload. Can anyone point me to a solution like this?
Thanks
If you're checking the file size you can use something like uploadify to check the file size before upload.
Checking the actual file dimensions (height / width) may need to be done on the server.
I think it is impossible unless you use a flash. You can use uploadify or swfupload for such things.
I have tested this code in chrome and it works fine.
var x = document.getElementById('APP_LOGO'); // get the file input element in your form
var f = x.files.item(0); // get only the first file from the list of files
var filesize = f.size;
alert("the size of the image is : "+filesize+" bytes");
var i = new Image();
var reader = new FileReader();
reader.readAsDataURL(f);
i.src=reader.result;
var imageWidth = i.width;
var imageHeight = i.height;
alert("the width of the image is : "+imageWidth);
alert("the height of the image is : "+imageHeight);
Something like this should cope with forms loaded asynchronously, inputs with or without "multiple" set and avoid the race conditions that happen when using FileReader.readAsDataURL and Image.src.
$('#formContainer').on('change', '#inputFileUpload', function(event) {
var file, _fn, _i, _len, _ref;
_ref = event.target.files;
_fn = function(file) {
var reader = new FileReader();
reader.onload = (function(f) {
return function() {
var i = new Image();
i.onload = (function(e) {
var height, width;
width = e.target.width;
height = e.target.height;
return doSomethingWith(width, height);
});
return i.src = reader.result;
};
})(file);
return reader.readAsDataURL(file);
};
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
file = _ref[_i];
_fn(file);
}
});
Note: Needs jQuery, HTML5, hooks to a structure like:
<div id="formContainer">
<form ...>
...
<input type="file" id="inputFileUpload"></input>
...
</form>
</div>
You need check image Width and Height when Image onload.
var img = new Image;
img.src = URL.createObjectURL(file);
img.onload = function() {
var picWidth = this.width;
var picHeight = this.height;
if (Number(picWidth) > maxwidth || Number(picHeight) > maxheight) {
alert("Maximum dimension of the image to be 1024px by 768px");
return false;
}
}
This works perfectly for me
var _URL = window.URL || window.webkitURL;
$("#file").change(function(e) {
var file, img;
if ((file = this.files[0])) {
img = new Image();
img.onload = function() {
if((this.width < 800)||(this.height < 400)){
alert('Image too small. Images must be bigger than 800 x 400');
$('#file').val('');
}
};
img.onerror = function() {
alert( "not a valid file: " + file.type);
};
img.src = _URL.createObjectURL(file);
}
});
Kudos to the original creator: http://jsfiddle.net/4N6D9/1/
I modified this to specify the min width and height of an upload.

Categories