Forum Moderators: open

Message Too Old, No Replies

Detect image dimensions on load and write height/width tags at 50%

         

timware

6:58 am on Mar 13, 2004 (gmt 0)

10+ Year Member



I will be creating many popup pages with an enlargement image that I want to display at 50% size in the window. The images will be different sizes, so I'm wondering if there's a way for the page, on load, to detect the image inlined on the page and write the height/width attributes at 50% dynamically.

So, if "chart.gif" is actually 1000 x 500 px, I'd like the height/width written dynamically into the <img> tag: width=500 height=250.

FYI, I'm doing this because the client wants to images to print nicely, and file size isn't an issue.

I hope this is clear. Thanks.

Tim

isitreal

6:43 pm on Mar 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You can do that very easily with php, doing it server side has many advantages, one of which it will always work in all cases, doesn't depend on users having javascript enabled.

image_absolute_path = $_SERVER['DOCUMENT_ROOT'] . $image_path_from_site_root;
$a_imageinfo = GetImageSize( $image_absolute_path );

$image_width_height = $a_imageinfo[3];

then print that out into your javascript popup.

$a_imageinfo[3] contains the value ' width='imagewidth' height='imageheight'
$a_imageinfo[0] contains just the width in pixels
$a_imageinfo[1] contains just the height in pixels

You can use the last two values to create the popup window size.

this is how I do it, it works flawlessly

timware

7:30 pm on Mar 14, 2004 (gmt 0)

10+ Year Member



Thanks! I got this to work and have it print out the image dimensions, but I'm a bit unsteady in taking the width/height values and dividing them by 2, rounded off. Can you help here? I really appreciate the help already provided. Here's the .php page:

<body>

<?php

$image_absolute_path = $_SERVER['DOCUMENT_ROOT'] . '/naomi_lg.jpg';

$a_imageinfo = GetImageSize( $image_absolute_path );

$image_width_height = $a_imageinfo[3];

?>

<br>

<?php

echo $a_imageinfo[3];

?>

Thanks! Tim

Birdman

9:43 pm on Mar 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Use the round() [php.net] function on getimagesize() [php.net] array() [php.net].

$image = getimagesize("/path/to/image");
$width = round($image[0]);
$height = round($image[1]);

timware

12:31 am on Mar 15, 2004 (gmt 0)

10+ Year Member



Sorry. I need a bit more help. I need to divide the width/height values in half and have them rounded. Thanks for the start, though.

Tim

Rambo Tribble

2:01 am on Mar 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



As your popups are probably being generated in JavaScript, I'm not sure it makes that much sense to use PHP for the sizing. JavaScript has to be enabled for it to work, anyway.

The Image object of an HTML page is an array holding the images in the page. You can use a for(condition){statement} loop to run through the array, document.images[i], with the loop terminated by the value returned by document.images.length. The height and width values of an individual image, i, in the array can be returned by document.images[i].height and document.images[i].width. You can then use JavaScript's math operators and the Math.round() function to return the divided and rounded value.

isitreal

5:02 am on Mar 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I was looking into the problem of extracting information out of things in javascript a while ago, it's a problem, that's why I gave up on it:

<script type="text/javascript">
for( i=0; i < document.images.length; i++)
{
width = document.images[i].width;
document.write(width);
height = document.images[i].height;
document.write(height);
}
</script>

Result: works in Mozilla. Period. I know there is a way around this but it's a pain, requires browser testing, and isn't very reliable from everything I've read, especially when you have php that works right out of the box, no tweaks. Since you can also use the php script to write the thumbnail size, so the page has its sizing information correctly, avoiding that resizing of the page that you see too often, it's not really that important if javascript is turned off or on, the image sizing is still being used, great way to write out galleries from arrays or databases, by the way.

So back to php:

$image = getimagesize("/path/to/image");
$width = round($image[0]/2);
$height = round($image[1]/2);

and you're set, you can't do that with $image[3] since that outputs a string, not a number, so you'll have to construct the image size using $image[0] and $image[1]

Rambo Tribble

1:52 pm on Mar 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Actually, isitreal, the code should be more like:
document.write('<img src=\"filename.jpg\" height=\"' +height_var+ '\" width=\"' +width_var+ '\" />');

You're just trying to create the HTML as it would normally be. This is true whether it is Moz or IE, JavaScript or PHP. Really, most stuff in any computer language is easy, if you understand the language and the goal. Granted, assembler is a little tougher than a scripting language, but PHP and JavaScript are very similar.

The advantage or disadvantages of PHP have more to do with the fact that it is server-side. Your script serves the image at reduced size. This can be an advantage, less bandwidth, or a disadvantage if the client wants to right click and save or view the image full size, which then means more scripting and another pair of transmissions back and forth to get the original image.

I think timware should be allowed to make his own decision based on his needs and preferences. What
we should provide is simply the facts, without partisanship.

timware

3:07 pm on Mar 15, 2004 (gmt 0)

10+ Year Member



First, I am non-partisan about this, just a pragmatist.

Second, the PHP isitreal has provided facilitates what I want to do, which is to *display* the image at a reduced viewing size, but have the image actually be much larger for better printing. And it allows me to just preload the images and not have to code in a size for its display or for the popup window.

I'm certainly still open to a JS that accomplishes the same thing as it's true that I'm using JS anyway to pop the window.

Hope I'm being clear here.

And to both, or all, of you. The help is greatly appreciated.

Tim

Rambo Tribble

3:11 pm on Mar 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you don't care to provide the images at original size, with lowest bandwidth consumption, stick with the PHP. It does give you two code bases to maintain, however.

With the JavaScript you are just using it to control the HTML display properties. If you aren't using document.write() to populate the popup already, i.e. you are just filling the popup with a URL, it probably makes sense to stick with the PHP. Alternatively, though, if you would like the image to occupy a certain portion of the popup, regardless of original image size, just use percentages for the image size attributes in the HTML for the page being loaded. That avoids scripting altogether.

Rambo Tribble

5:16 pm on Mar 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Actually, the percentage trick would work as well with the document.write() method. Remember your percentages are of the total browser window. As there is usually more chrome top to bottom, that will affect the results.

If your images vary substantially in aspect ratio, the percentage trick probably won't give a good result. It all depends on how many aspect ratios you must support whether scripting is necessary.

timware

6:12 pm on Mar 15, 2004 (gmt 0)

10+ Year Member



I tried just setting the image height and width attributes to 50% and this seemed to work fine. I also want to use the image size to set the size of the popup and I think I can do this with the PHP, just by simple addition to the $width & $height. Thanks again, BTW.

Tim

isitreal

6:35 pm on Mar 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Rambo Tribble: The suggestion you gave does not work except on mozilla browsers, as I noted, it was not a solution, and so was of no use to the original poster. Your response seems to suggest that you had offered an equal solution, but you didn't.

If you would like to present an actual solution in javascript that works that would be great, I for one would like to see it, but I think you'll find that it's quite a bit more difficult than you think if you want it to work cross browser. The php solution works in all cases, immediately, and will never require a page update to fix the code when a new browser version comes out that has some other way of reading the image data. It also creates the image sizing before the page loads, meaning that the html is delivered including the correct image size.

You'll also note that the images need to be loaded into document.images to begin with, whereas the php solution reads the actual image file and uses that data to create the image size.

Personally, I would not make the thumbnails sized as 1/2 size of the full images, but would generate highly optimized, relatively low resolution for the page, then use the full resolution jpg for the popup, this speeds up page load radically.

It's relatively trivial to add this feature to the php image sizing code, all you have to do is concatenate 'th_' to the file name, run the getimagesize() function on that file name, then the size for the thumbnail can be put onto the thumnail image on the page as well as the sizes for the full sized popup versions, one piece of code, very simple, very stable, always works.

I don't use javascript anymore for page functionality, only for additional features that aren't that critical, or that are so basic, like making a popup or whatever, or that simply can't be done server side.

Rambo Tribble

3:11 am on Mar 16, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



isitreal:

I think you misinterpret my comments. While I readily admit there advantages to server side scripts in many circumstances, there are also many occasions when client side scripts are advantageous.

DHTML effects such as rollovers and tabbed divisions, forms validation, immediate calculations from user input, clocks and other useful features are best handled at the client. Let's not forget, also, that not every hosting situation supports server side scripts.

Whether Tim's situation is best resolved with server side or client side scripts is his call. I just want him to have the information to make an informed decision. It appears that he is already downloading the full-sized images for print and simply wants to display them at reduced size. If that is true, a separate thumbnail would actually use more bandwidth. Actually, it isn't necessary to load the images into the document in order to manipulate them; the images can be preloaded into variables or an array and their attributes determined from there before the HTML page is built. That is how most of the old JavaScript rollovers worked.

Finally, the code I provided works fine for me on IE 5 & 6, Mozilla and Opera. If you're having problems with similar scripts, perhaps you could post the code you are using and I can help you find the problem.

Birdman

12:07 pm on Mar 16, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Tim,

My appologies! The code I gave was wrong, as I'm sure you noticed. It should have read:

$image = getimagesize("/path/to/image");
$width = round($image[0] * .5);
$height = round($image[1] * .5);

OR:

$image = getimagesize("/path/to/image");
$width = round($image[0] / 2);
$height = round($image[1] / 2);

Rambo Tribble

4:07 am on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Tim,

Did you get your problems under control? I'll have some time free tomorrow, and could whip a quick JS script out to size your windows or images, if I knew more about when in the process you are downloading the images. Oh, and the number of images and whether they have totally unique names or use a pattern like image_01.jpg, image_02.jpg, etc.

isitreal:

It occurs to me your problems probably orignated in the images not having finished downloading before the function fired. Call it with onload() if you are loading the body with images first; use a for statement to recursively check if Image objects are loaded into variables or an array(no longer "undefined"). Use a timeout on the loop to avoid thrash.

isitreal

9:55 pm on Mar 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



rambotrimble: thanks for clarifying. You didn't however provide a working example of any code, and still haven't.

that's all I was saying. If you want to provide a working example of the code then I'll take a look at it, I was testing this on my development server so I don't think the image loading was the problem, although that could be wrong.

Usually when I answer a programming question here I make a working version, test it thoroughly cross browser, then post it. That saves headaches and miscommunications.

The js code I posted above only works on moz, and that was based on the fragments you suggested.

I'm also not saying to use only js or php, I use both, but when it comes to page construction I am getting away from using js for anything, it's just not very reliable, and debugging js for browser specific failures is not my idea of a fun way to spend my time, so I tend to keep it very basic, except when I want to show some technique off in dynamic real time.

Rambo Tribble

11:36 pm on Mar 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



isitreal:

Don't have much time at the moment, just home for lunch. I'll try to cook up a pared-down example this evening. I doubt you want to sift through 100 lines of code for the dozen you need. In the mean time, you might just try window. on the front of your document. scope chain. Every once in a while I found a browser balks if you aren't specific.

isitreal

12:06 am on Mar 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Ok, thanks, but I never use javascript for this kind of stuff anymore, it just doesn't work as well as php. It was more for the person who started the thread.

My goal now is for pages to display pretty much the same with or without js enabled, so if it's disabled all that happens is that certain features won't work, but won't really affect the user's experience.

the thing that is really hard is getting data from existing css id's though, like

width = document.getElementById('image_id').style.width; or whatever, that's the tough one.

document.images is one of the more stable js things, but still when you are building any kind of gallery page the images all have to be preloaded before you can access their information as far as I know, that means that the page can only build after the images are loaded, with the php solution php accesses the actual image file and gets the width and height data directly, before building the page, that's why I consider it a significantly better option in this case, since the html will load almost instantly, then the image will load into their sized img tags. Very neat, simple.

Rambo Tribble

3:09 am on Mar 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I quite agree with you, in the circumstance you cite. Server side scripts are superior for delivering already modified content; JavaScript has advantages for on-the-fly modifications. Each has its purpose and each is an easy language to work with. They're quite similar, actually. Nowhere near as picky and demanding as Java, but again, Java definitely has its purpose. And of course, Java has more class (pun intended).

It sounds as though the JavaScript image size reading is a low priority for you, so I won't dig out the scripts right now. I have some publishing deadlines to deal with at the moment. I am sure the JavaScript can be made to work, cross-browser. You are absolutely right, the images must first be loaded into either a JavaScript array or the page's image array, before attributes can be read. Most of the time I've loaded them into a JavaScript array, but the window.document.images[] array should function similarly, once the onload condition is met.

I do remember having a problem, I'm pretty sure it was with IE, trying to get it to address some document objects, unless window. was included in the scope chain. As I recall, the code worked fine in Mozilla (my usual test bed), but bombed in IE. It took an hour or two of fussing before I realized the problem.

isitreal

4:29 am on Mar 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If you have the time to post that code I'd like to see it, but don't worry about it, thanks.

I read up a bit on getting information out of elements, it's not quite as simple as you say if I read it right, it struck me as not worth the time to learn, but as techniques go, it's one I'd like to have a better grasp on, that's for sure.

Rambo Tribble

5:18 am on Mar 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a slight variant on your code, which works on IE 5 & 6 for me on Win XP (though OS should make no difference):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<script type="text/javascript">
function showImgDim(){
for( i=0; i < window.document.images.length; i++)
{
wth = window.document.images[i].width;
hgt = window.document.images[i].height;
w_n_h=wth+" "+hgt;
alert(w_n_h)
}
}
</script>
</head>
<body onload="showImgDim();">
<img src="your_image.jpg" />
</body>
</html>

I hope this helps. Let me know if you need more.

isitreal

5:22 pm on Mar 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, that did it, thanks for taking the time to post it. Works on all browsers I tested it on.

Now if you ever feel like posting code to get information out of the document.getElementById properties... that works cross browser too, that would be great.

like

width = document.getElementBy(element_id).style.width;