views:

329

answers:

4

Hi,

I have file upload UI element in which the user will upload images. Here I have to validate the height and width of the image in client side. Is it possible to find the size of the image having only the file path in JS?

Note: If No, is there any other way to find the dimensions in Client side?

+1  A: 

No, You can't, filename and file content are send to the server in http headerbody, javascript cannot manipulate those fields.

S.Mark
Is there any other way to find the dimensions in Client side?
Sri Kumar
You need to upload it to somewhere else, check it in server and get those value back with ajax
S.Mark
I am not sure flash can do it or not, but java applet should be able to do that. or looks like html5 could do that, see T.J. Crowder's answer
S.Mark
Thanks Mark for the info :)
Sri Kumar
Welcome!, and looks like flash also can do it. you could take a look code poet answer. flash supposed to be done at client side
S.Mark
+4  A: 

You can do this on browsers that support the new File API from the W3C, using the readAsDataURL function on the FileReader interface and assigning the data URL to the src of an img (after which you can read the height and width of the image). Currently Firefox 3.6 supports the File API, and I think Chrome and Safari either already do or are about to.

So your logic during the transitional phase would be something like this:

  1. Detect whether the browser supports the File API (which is easy: if (typeof window.FileReader === 'function')).

  2. If it does, great, read the data locally and insert it in an image to find the dimensions.

  3. If not, upload the file to the server (probably submitting the form from an iframe to avoid leaving the page), and then poll the server asking how big the image is (or just asking for the uploaded image, if you prefer).

Edit I've been meaning to work up an example of the File API for some time; here's one:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Show Image Dimensions Locally</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
</style>
<script type='text/javascript'>

    function loadImage() {
        var input, file, fr, img;

        if (typeof window.FileReader !== 'function') {
            write("The file API isn't supported on this browser yet.");
            return;
        }

        input = document.getElementById('imgfile');
        if (!input) {
            write("Um, couldn't find the imgfile element.");
        }
        else if (!input.files) {
            write("This browser doesn't seem to support the `files` property of file inputs.");
        }
        else if (!input.files[0]) {
            write("Please select a file before clicking 'Load'");
        }
        else {
            file = input.files[0];
            fr = new FileReader();
            fr.onload = createImage;
            fr.readAsDataURL(file);
        }

        function createImage() {
            img = document.createElement('img');
            img.onload = imageLoaded;
            img.style.display = 'none'; // If you don't want it showing
            img.src = fr.result;
            document.body.appendChild(img);
        }

        function imageLoaded() {
            write(img.width + "x" + img.height);
            // This next bit removes the image, which is obviously optional -- perhaps you want
            // to do something with it!
            img.parentNode.removeChild(img);
            img = undefined;
        }

        function write(msg) {
            var p = document.createElement('p');
            p.innerHTML = msg;
            document.body.appendChild(p);
        }
    }

</script>
</head>
<body>
<form action='#' onsubmit="return false;">
<input type='file' id='imgfile'>
<input type='button' id='btnLoad' value='Load' onclick='loadImage();'>
</form>
</body>
</html>

Works great on Firefox 3.6. I avoided using any library there, so apologies for the attribute (DOM0) style event handlers and such.

T.J. Crowder
+1 , thats the way to do it.
S.Mark
Thanks for the example!
Pointy
+1  A: 

If you use a flash based uploaded such as SWFUpload you can have all the info you want as well as multiple queued uploads.

I recommend SWFUpload and am in no way associated with them other than as a user.

You could also write a silverlight control to pick your file and upload it.

Sky Sanders
+1 looks cool !
S.Mark
Of course, this requires that your users allow Flash. A lot of us block Flash as a matter of course, for the moment, because of all the Flash-based ads.
T.J. Crowder
@TJC granted, but until HTML5 is ubiquitous Flash/ActiveX/Silverlight/XBap is the only viable option for this kind of situation.
Sky Sanders
@code poet: Indeed, yes. :-) For me, I'd just do HTML5 or server-side, but certainly an option would be HTML5, fall back to (insert proprietary technology here), fall back to server-side. :-)
T.J. Crowder
@TJC - that is always the really frustrating aspect of all of the new toys like HTML5 and native JSON - until they are ubiquitous they are little more than novelty from a production perspective. We are still supporting IE6 for cryin out loud!
Sky Sanders
A: 

HTML5 is definitely the correct solution here. You should always code for the future, not the past. The best way to deal with HTML4 browsers is to either fall back on degraded functionality or use Flash (but only if the browser does not support the HTML5 file API)

Using the img.onload event will enable you to recover the dimensions of the file. Its working for an app I'm working on.

Guy Thomas