Chrome bug related to .naturalWidth? - javascript

It seems that the below code randomly produces aImg.naturalWidth either the real width of the picture or 0. Is it a Chrome 70.0.3538.67 for Linux bug?
If it is not a bug, how to make it work right (not to return 0)?
function handleImageFile(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file.type != 'image/jpeg') continue;
var img = document.createElement("img");
img.file = file;
var reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
$('#newPictureContainer').css('display', 'block');
document.getElementById('newPicture').appendChild(img);
aImg.src = e.target.result;
if (aImg.naturalWidth >= 300 || aImg.naturalHeight >= 300) {
if (aImg.naturalWidth <= aImg.naturalHeight)
aImg.width = 300;
else
aImg.height = 300;
$('#selectPicture').css('display', 'none');
} else {
$('#selectPicture [type=file]').val("");
alert("The smallest side of the picture should be at least 300 pixels.");
}
};
})(img);
reader.readAsDataURL(file);
}
}
<div id="selectPicture" style="display:block">
<input type="file" name="imageUpload" onchange="handleImageFile(this.files)"/>
</div>
<div id="newPictureContainer" style="display:none">
<span id="newPicture"></span>
<img src="/include/javascript/israelinfo/multiuploader/images/cross-small.gif"
width="16" height="16" title="Удалить" alt="Delete" class="MUdelete"
onclick="closePicture()">
</div>

#JᴀʏMᴇᴇ gave an answer:
I must access .naturalWidth in a handler of onload of the image not one of FileReader.
I mistakenly assumed that the image is loaded immediately after assigning a data: URL to .src. It seems not to be the case.

Related

Summernote rich text editor-restrict image above particular height and width

When I upload image in editor, I am able to find it's size.
But I want it's height and width to restrict for height and width above particular limit.
Below is result which I'm getting when I upload image.
See image to image upload result
For size restriction it's working as below-
onImageUpload(images, insertImage) {
if (images[0].size <= 100000) {
for (let i = 0; i < images.length; i++) {
const reader = new FileReader();
reader.onloadend = () => {
insertImage(reader.result);
};
reader.readAsDataURL(images[i]);
}
} else {
alert('Image not saved, max allowed image size is 100kb');
}
};
What editor are you using? UEditor is a very good rich-text editor.
onImageUpload(images, insertImage) {
console.log('onImageUpload', images);
if (images[0].size <= 100000) {
for (let i = 0; i < images.length; i++) {
const reader = new FileReader();
reader.onloadend = () => {
var i = new Image();
i.src = reader.result;
i.onload = function () {
if (i.width <= 200 && i.height <= 200) {
insertImage(reader.result);
} else {
cogoToast.warn('Image not saved, image width and height should be less than 200*200');
}
};
};
reader.readAsDataURL(images[i]);
}
} else {
cogoToast.warn('Image not saved, max allowed image size is 100kb');
}
};
It will work in this way.Thanks!

Javascript - if boolean true not working

So, i created the following function to check the file uploaded by user is
1) Image only
2) Size less than maxSize KBs
3) Dimensions less than maxWidth and maxHeight
All else is working fine except that the condition where I check dimensions. The value in dimensions is indeed the correct value but the condition if(dimensions) doesn't run even when dimensions=true.
Is there something I am doing wrong?
var maxThumbnailWidth = '1050';
var maxThumbnailHeight = '700';
var maxThumbnailSize = '60';
function imageFileChecks(file, type) // type here refers to either Image or Banner or Thumbnail
{
var maxSize;
var maxWidth;
var maxHeight;
var dimensions = false;
if (type == 'image') {
maxSize = maxImageSize;
maxWidth = maxImageWidth;
maxHeight = maxImageHeight;
}
if (type == 'banner') {
maxSize = maxBannerSize;
maxWidth = maxBannerWidth;
maxHeight = maxBannerHeight;
}
if (type == 'thumbnail') {
maxSize = maxThumbnailSize;
maxWidth = maxThumbnailWidth;
maxHeight = maxThumbnailHeight;
}
//First check file type.. Allow only images
if (file.type.match('image.*')) {
var size = (file.size / 1024).toFixed(0);
size = parseInt(size);
console.log('size is ' + size + ' and max size is ' + maxSize);
if (size <= maxSize) {
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 width sizes', sizes.width);
console.log('onload height sizes', sizes.height);
var width = parseInt(sizes.width);
var height = parseInt(sizes.height);
if (width <= maxWidth && height <= maxHeight) {
dimensions = true;
console.log('dimensions = ', dimensions);
}
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
if (dimensions) {
alert('here in dimensions true');
sign_request(file, function(response) {
upload(file, response.signed_request, response.url, function() {
imageURL = response.url;
alert('all went well and image uploaded!');
return imageURL;
})
})
} else {
return errorMsg = 'Image dimensions not correct!';
}
} else {
return errorMsg = 'Image size not correct!';
}
} else {
return errorMsg = 'Image Type not correct!';
}
}
<div class="form-group">
<label class="col-md-6 col-xs-12 control-label">Thumbnail</label>
<div class="col-md-6 col-xs-12">
<input type="file" id="thumbnail" class="file" required>
<br>
</div>
</div>
<script type="text/javascript">
document.getElementById('thumbnail').onchange = function() {
var file = document.getElementById('thumbnail').files[0];
if (!file) {
console.log("ji");
return;
}
var type = 'thumbnail';
var thumbnailURL = imageFileChecks(file, type);
}
</script>
This seems like an async issue -- your if(dimensions) statement is running before your img.onload function finishes, in which case dimensions would be equal to false when you get to that part in your code, despite the img.onload function and its logic executing correctly.
You could try nesting the if(dimensions) condition in the img.onload function.
You set your dimension property inside the img.onload callback function.
This will not be executed directly. Then you check the value directly below, which will not be set yet. This is the nature of JavaScript: async functions being queued up to run at some time (example when an image finished loading).
To solve your problem, you need to make the rest of your function execute after img load. This can be done with either callback functions or promises.
I would read up on the asynchronous behavior a bit. Sorry for not providing a link, but should be plenty out there!
#William is right.You can handle it like that
function loadImage(src,callback){
var img = new Image();
img.onload = function() {
if (callback) {
callback(img);
}
}
img.src = src;
}

Jquery Image preview error

The requirement:
I am trying preview an image before uploading. So I come up with this code:
function readURL(input)
{
if (input.files && input.files[0])
{
var reader = new FileReader();
reader.onload = function (e) {
$('#preview').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
And I am calling the function by this method:
$(document).ready(function(){
$('#image').on('change',function(e){
readURL(this);
});
});
The code is working fine. Now the HTML is this:-
<div class="control-group">
<label class="control-label" for="fileInput"><?php echo ucfirst($entity); ?> Image :</label>
<div class="controls">
<input class="input-file uniform_on" name="image" id="image" type="file"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="fileInput">Image Preview:</label>
<div class="controls">
<img src="#" name="preview" id="preview" height="100" alt="Preview Image"/>
</div>
</div>
Till now the code is running smooth.
Now I want to update my code based on these requirements:-
First the imageSize will be checked, whether it's less than 300KB.
Then it will check if the dimension is less than 1200x1200
If the file is less than 300KB and size less than 1200x1200, then the preview will be displayed.
So I made the following changes:-
var maxImageSize = parseInt(3000) * 100; //3KB * 100 = 300KB
var maxImageWidth = 1200;
var maxImageHeight = 1200;
function readURL(input)
{
if (input.files && input.files[0])
{
var reader = new FileReader();
reader.onload = function (e) {
$('#preview').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$(document).ready(function(){
$('#image').on('change',function(e){
var imageSize = this.files[0].size;
if(imageSize > maxImageSize)
{
if(maxImageSize>=1000 && maxImageSize<1000000)
{
var allowedSize = parseFloat(parseInt(maxImageSize)/1000)+' KB';
}
else if(maxImageSize>=1000000)
{
var allowedSize = parseFloat(parseInt(maxImageSize)/1000000)+' MB';
}
var $el = $('#image');
$el.wrap('<form>').closest('form').get(0).reset();
$el.unwrap();
var html = '<strong>Severe Error</strong><p>Max. filesize allowed is '+allowedSize+'</p>';
$('#modalError').html(html);
$('#modalError').show();
$('#modal').modal();
}
else
{
var imgFile = this.files[0];
var img = new Image();
img.src = window.URL.createObjectURL(imgFile);
img.onload = function() {
var imgField = $('#image');
var imgWidth = img.naturalWidth, imgHeight = img.naturalHeight;
if(imgWidth>maxImageWidth && imgHeight>maxImageHeight)
{
var html = '<strong>Severe Error</strong><p>Max. width allowed is '+maxImageWidth+'px & Max. height allowed is '+maxImageHeight+'px</p>';
$('#modalError').html(html);
$('#modalError').show();
$('#modal').modal();
}
else
{
readURL(imgField);
}
};
}
});
});
In the above code, the size and dimension validation is working fine. However, the image is not getting previewed.
What am I doing wrong?
You are passing an <img> to readURL instead of a File object at readURL(imgField)

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

Categories

Resources