I have a image resizer function that resize images proportional. On every image load a call this function with image and resize if its width or height is bigger than my max width and max height. I can get img.width and img.height in FF Chrome Opera Safari but IE fails. How can i handle this?
Let me explain with a piece of code.
<img src="images/img01.png" onload="window.onImageLoad(this, 120, 120)" />
function onImageLoad(img, maxWidth, maxHeight) {
var width = img.width; // Problem is in here
var height = img.height // Problem is in here
}
In my highligted lines img.width don't work on IE series.
Any suggestion?
Thanks.
Don't use width and height. Use naturalWidth and naturalHeight instead. These provide the image unscaled pixel dimensions from the image file and will work across browsers.
Man, I was looking for this for 2 days. Thanks.
I'm using jQuery, but it doesnt matter. Problem is related to javascript in IE.
My previous code:
var parentItem = $('<div/>')
.hide(); // sets display to 'none'
var childImage = $('<img/>')
.attr("src", src)
.appendTo(parentItem) // sets parent to image
.load(function(){
alert(this.width); // at this point image is not displayed, because parents display parameter is set to 'none' - IE gives you value '0'
});
This is working in FF, Opera and Safari but no IE. I was getting '0' in IE.
Workaround for me:
var parentItem = $('<div/>')
.hide();
var childImage = $('<img/>')
.attr("src", src)
.load(function(){
alert(this.width); // at this point image css display is NOT 'none' - IE gives you correct value
childImage.appendTo(parentItem); // sets parent to image
});
This is how I solved it (because it's the only js on the site I didn't want to use a library).
var imageElement = document.createElement('img');
imageElement.src = el.href; // taken from a link cuz I want it to work even with no script
imageElement.style.display = 'none';
var imageLoader = new Image();
imageLoader.src = el.href;
imageLoader.onload = function() {
loaderElement.parentElement.removeChild(loaderElement);
imageElement.style.position = 'absolute';
imageElement.style.top = '50%';
imageElement.style.left = '50%';
// here using the imageLoaders size instead of the imageElement..
imageElement.style.marginTop = '-' + (parseInt(imageLoader.height) / 2) + 'px';
imageElement.style.marginLeft = '-' + (parseInt(imageLoader.width) / 2) + 'px';
imageElement.style.display = 'block';
}
It's because IE can't calculate width and height of display: none images. Use visibility: hidden instead.
Try
function onImageLoad(img, maxWidth, maxHeight) {
var width = img.width; // Problem is in here
var height = img.height // Problem is in here
if (height==0 && img.complete){
setTimeOut(function(){onImageLoad(img, maxWidth, maxHeight);},50);
}
}
var screenW = screen.width;
var screenH = screen.height;
//alert( screenW );
function checkFotoWidth( img, maxw )
{
if( maxw==undefined)
maxw = 200;
var imgW = GetImageWidth(img.src);
var imgH = GetImageHeight(img.src);
//alert(GetImageWidth(img.src).toString()); // img.width); // objToString(img));
if (imgW > maxw || (img.style.cursor == "hand" && imgW == maxw))
{
if (imgW > screenW) winW = screenW;
else winW = imgW;
if (imgH > screenH) winH = screenH;
else winH = imgH;
img.width=maxw;
img.style.cursor = "pointer";
img.WinW = winW;
img.WinH = winH;
//alert("winW : " + img.WinW);
img.onclick = function() { openCenteredWindow("Dialogs/ZoomWin.aspx?img=" + this.src, this.WinW, this.WinH, '', 'resizable=1'); }
img.alt = "Klik voor een uitvergroting :: click to enlarge :: klicken Sie um das Bild zu vergrössern";
//alert("adding onclick);
}
}
function GetImageWidth(imgSrc)
{
var img = new Image();
img.src = imgSrc;
return img.width;
}
function GetImageHeight(imgSrc)
{
var img = new Image();
img.src = imgSrc;
return img.height;
}
I'd try this:
function onImageLoad(img, maxWidth, maxHeight) {
var width, height;
if ('currentStyle' in img) {
width = img.currentStyle.width;
height = img.currentStyle.height;
}
else {
width = img.width;
height = img.height;
}
// whatever
}
edit — and apparently if I were to try that I'd learn it doesn't work :-) OK, well "width" and "height" definitely seem to be attributes of <img> elements as far as IE is concerned. Maybe the problem is that the "load" event is firing for the element at the wrong time. To check whether that's the case, I would then try this:
function onImageLoad(img, maxWidth, maxHeight) {
var width, height;
var i = new Image();
i.onload = function() {
width = i.width; height = i.height;
// ... stuff you want to do ...
};
i.src = img.href;
}
getDisplay().getImage().setUrl(imgURL);
final Image img = new Image(imgURL);
int w=img.getWidth();
int h=img.getHeight();
Related
I am currently running into a problem with my code. I am attempting to set the height of an image through JavaScript in a check that its less than 600 pixels. I have tried a plethora of alternatives to the general "this.height = 600" but none have resulted successfully. I am really hoping someone can help me fix this problem.
<div id="cursedframe">
<img src="" id="cursedimg">
</div>
<script>
function setImage() {
var img = new Image();
var images = [
"bean.jpg",
"xxx-edit-parallax/Images/xxx-5.jpg"
];
var chosen = images[Math.floor(Math.random() * images.length)];
img.onload = function(){
if (this.height > 600) {
console.log("more than");
this.height = 600;
console.log(img.height);
} else {
console.log("less than");
this.height = "auto";
console.log(this.height);
}
};
img.src = chosen.toString();
document.getElementById("cursedimg").src = img.src;
}
</script>
It successfully passes the "if" but never actually sets the height.
EDIT: Unaware of the CSS property of max-height and max-width at the time. Was brought to my attention by Lain. Thank you
It would be much easier to use the css property max-height.
Just to show the actual flaw with the approach in javascript: you have to pass the height on to the actual image. Currently you merely set it to the img object yet never to the shown image <img src="" id="cursedimg">.
var img = new Image();
var images = ['https://logosmarken.com/wp-content/uploads/2018/05/Google-Logo.png'];
var maxHeight = 200; //REM: For my test image
img.onload = function(){
if (this.height > maxHeight) {
console.log("more than");
this.height = maxHeight;
console.log(img.height);
} else {
console.log("less than");
this.height = "auto";
console.log(this.height);
};
//REM: Here you need to assign the src along with the height
document.getElementById("cursedimg").src = this.src;
document.getElementById("cursedimg").style.height = this.height + 'px';
};
//REM: No need for toString() - it already is.
img.src = images[Math.floor(Math.random() * images.length)];
<div id="cursedframe">
<img src="" id="cursedimg">
</div>
Even easier would be to not create a new object at all and just assign it as is:
var img = document.getElementById("cursedimg");
By running the following code, you are assigning the only the src attribute to the img element
img.src = chosen.toString();
document.getElementById("cursedimg").src = img.src;
If you want to set the height and src of the image element using javascript,
you can do the following:
var image = document.getElementById("cursedimg");
if ( image.height > 600 ){
image.height = 600;
}
else{
image.style.height = "auto"; // since 'auto' is a styling value
}
image.src = chosen.toString();
I am struggling with an issue that I can't define. I've pieced together this JQuery for uploading an image. When generating the preview, I'm using FileReader to get the image dimensions in order to control the resizing of the preview. As far as I can tell, that is working fine when I do console.log ($preview); inside img.onload = function() {};. But If I do that outside the function, it is undefined. I need access to the variable in the following functions. I've been studying scope, and from what I understand if I don't declare the variable inside the function like var variable = x; it shouldn't be local. I've also searched and searched the internet and SO for a solution but nothing seems to fit.
Is this an asynchronous issue or is it an issue with scope even though $preview is defined initially outside these functions? Can I return it from inside the function like in PHP?
var $preview;
if (previewsOn) {
if (isImgFile(ui.file)) {
var reader = new FileReader;
reader.onload = function() {
var img = new Image;
img.onload = function() {
if (img.width > 120 || img.height > 100) {
var maxWidth = 120;
var maxHeight = 100;
var ratio = 0;
var width = img.width;
var height = img.height;
if (width > maxWidth){
ratio = maxWidth / width;
$preview = $('<img/>').css("width", maxWidth);
$preview = $('<img/>').css("height", height * ratio);
height = height * ratio;
width = width * ratio;
}
if (height > maxHeight){
ratio = maxHeight / height;
$preview = $('<img/>').css("height", maxHeight);
$preview = $('<img/>').css("width", width * ratio);
width = width * ratio;
height = height * ratio;
}
} else {
$preview = $('<img/>');
}
};
img.src = reader.result;
};
reader.readAsDataURL(ui.file);
ui.readAs('DataURL', function(e) {
$preview.attr('src', e.target.result);
});
} else {
$preview = $('<i/>');
ui.readAs('Text', function(e) {
$preview.text(e.target.result.substr(0, 15) + '...');
});
}
} else {
$preview = $('<i>no preview</i>');
}
$($previewImg).empty(); $($preview).appendTo($previewImg);
$('<td/>').text(Math.round(ui.file.size / 1024) + ' KB').appendTo($row);
$('<td/>').append($pbWrapper).appendTo($row);
$('<td/>').append($cancelBtn).appendTo($row);
return $progressBar;
};
You assign value to $preview in .onload handler, but it is called some time later. According to your code following change could help:
var $preview;
if (previewsOn) {
if (isImgFile(ui.file)) {
$preview = $("<img/>");
(added initialization code after if statement)
Then replace lines like
$preview = $('<img/>').css("width", maxWidth);
with
$preview.css("width", maxWidth);
And remove
} else {
$preview = $('<img/>');
So variable will not be re-assigned.
answer to comment
Failure scenario timeline:
you code registers onload handler
you code continues execution, trying to do smth with $preview, which has no value yet
image finally loaded and onload handler triggered, assigning value to $preview
I'm using this plugin to create image zoom and gallery, yet I want to scale all images to fit with the container (using ratio algorithm).
Here is ratio function :
function scaleSize(maxW, maxH, currW, currH){
var ratio = currH / currW;
if(currW >= maxW && ratio <= 1){
currW = maxW;
currH = currW * ratio;
} else if(currH >= maxH){
currH = maxH;
currW = currH / ratio;
}
return [currW, currH];
}
And this is how the gallery load images :
var img = $('<img>').load(function(){
img.appendTo(a);
image_container.html(a);
}).attr('src', src).addClass(opts.big_image_class);
What I've tried :
var newSize = scaleSize(300, 320, $(".simpleLens-big-image").width(), $(".simpleLens-big-image").height());
var img = $('<img>').load(function(){
img.appendTo(a);
image_container.html(a);
}).attr('src', src).addClass(opts.big_image_class).width(newSize[0]).height(newSize[1]);
But scaleSize is not working properly since the current width and height is not yet defined (image not yet exist in dom).
Thanks for any pointers.
I took a look into plugin code and think you call your scaleSize() too early. An image with class simpleLens-big-image exists first after var img is set up and addClass() is done.
Try following:
var img = $('<img>').load(function(){
img.appendTo(a);
image_container.html(a);
}).attr('src', src).addClass(opts.big_image_class);
// at this point img should contain $(".simpleLens-big-image") so we can refer to img
var newSize = scaleSize(300, 320, img[0].naturalWidth, img[0].naturalHeight());
img.width(newSize[0]).height(newSize[1]);
Try something like this and call the onload method. This will make sure that the image is loaded to the DOM before you resize
var img = $('<img>');
img.src = src ;
img.onload = function() {
// Run onload code.
} ;
Looking for a way to get the dimensions (width and height) of an external image. I have used prop() and attr(), but they don't return any values. Just an error.
Example:
some link
jQuery
var path = 'https://source.unsplash.com/random/600x300/?montreal';
$("<img/>").attr('src', path).load(function() {
console.log(this.width, this.height);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
Vanilla Javascript
var path = 'https://source.unsplash.com/random/600x300/?montreal';
var img = new Image();
img.src = path;
img.addEventListener('load', function() {
console.log(this.width, this.height);
});
Looks like none has provided a working vanilla js answer.
var img = document.createElement('img')
img.src = 'http://domain.com/img.png'
img.onload = function() {
console.log( this.width )
console.log( this.height )
}
Here is a jsfiddle: http://jsfiddle.net/Ralt/VMfVZ/
This isn't technically jQuery but I would go down the route of:
var image = new Image(), width, height;
image.src = 'http://whereyourimage.is/heresmyimage.jpg';
width = image.width;
height = image.height;
You can then access those values using width and height, for example alert('My image is ' + width + ' pixels accross.');
I have JS which resize the width and height of Image which is working fine if I used Alert before assigning the actual image src to the image object and if I omit the alertbox, it is not working. Please suggest me how to fix it.
`
<html>
<head>
<script type="text/javascript" language="javascript">
function resize_image_height_weight(id, hgt, wdth)
{
//alert(id);
Obj=document.getElementById(id);
myImage = new Image();
myImage.src = Obj.src;
var heights = myImage.height;
var widths = myImage.width;
// alert("Height=>" + heights + " Width=> " + widths);
if(heights > hgt || widths > wdth)
{
if(heights > widths)
{
var temp = heights/hgt;
var new_width = widths / temp;
new_width = parseInt(new_width);
heights = hgt;
widths = new_width;
}
else
{
var temp = widths/wdth;
var new_height = heights / temp;
new_height = parseInt(new_height);
heights = new_height;
widths = wdth;
}
}
Obj.height = heights;
Obj.width = widths;
}
</script>
</head>
<body>
<div>
<center>
<img src="http://www.google.co.in/intl/en_com/images/srpr/logo1w.png" id="i" alt="Google logo" height="150" width="150">
<script type="text/javascript">
document.images[document.images.length-1].onload = resize_image_height_weight("i",150,150);
</script>
</center>
</div>
</body>
</html>`
When you set the .src on an image, you have to wait until the image is successfully loaded until you can read it's height and width. There is an onload event handler that will tell you when the image is loaded.
Here's a place in your code where this issue could occur:
Obj=document.getElementById(id);
myImage = new Image();
myImage.src = Obj.src;
var heights = myImage.height;
var widths = myImage.width;
In this case, since the image was already elsewhere in the document, you should just read the height and width off the existing element rather than the new element.
Be very careful when testing because if the image is in your browser cache, it may load immediately, but when it's not in your cache, it takes some time to load and won't be available immediately.
Putting an alert at the right place in your script can allow the image to load before the script proceeds which could explain why it works with the alert.
As RobG mentions, your onload handler is also faulty (needs to be a function, not the returned result of a function).
Here's a simpler function to scale an image to fit the bounds. This uses a trick that you only need to set one size (height or width on the image) and the other will be scaled by the browser to preserve the aspect ratio.
function resizeImage(id, maxHeight, maxWidth) {
// assumes the image is already loaded
// assume no height and width is being forced on it yet
var img = document.getElementById(id);
var height = img.height || 0;
var width = img.width || 0;
if (height > maxHeight || width > maxWidth) {
var aspect = height / width;
var maxAspect = maxHeight / maxWidth;
if (aspect > maxAspect) {
img.style.height = maxHeight + "px";
} else {
img.style.width = maxWidth + "px";
}
}
}
You can see it in action here: http://jsfiddle.net/jfriend00/BeJg4/.
In the function assigned to onload:
> document.images[document.images.length-1].onload =
> resize_image_height_weight("i",150,150);
you are assigning the result of calling resize_image_height_weight which throws an error in IE. Set it to a function instead:
document.images[document.images.length-1].onload = function() {
resize_image_height_weight("i",150,150);
};