Saturday, 16 February 2013

Code Tip #3 - Classic ASP Image Resizer (with options for cropping, padding, colouring and saving)

Like many other developers we're very comfortable using classic ASP and on the whole it does everything we need.

We know we should start moving across to VB.Net, but can't see many real benefits to compensate for the required learning curve.

The Problem


We'd like to be able to quickly and easily resize images and ASP doesn't offer any native commands, whereas VB.Net does.

After scouring the internet we came across a free ASP resizer from Pieter Cooreman, developer of a Classic ASP website content management system called QuickerSite.

His solution was simple. Use an aspx page to do the work and call it from a normal asp page.

Our Solution


We tried it and it worked perfectly, but there were a couple of things we wanted it to do that Pieter's code didn't, so we adapted it to include more querystring options, annotation and instructions.

The resulting image resizer will do the following:

  • Accept and convert jpeg, png, gif and bitmap files.
  • Convert images at a relative size to a given width or height.
  • Resize to a fixed width, either cropping or padding (with colour) the resulting image if the dimensions differ.
  • Add special effects including greyscale and sepia.
  • Output the resulting jpg to either the screen, a file or both.

All you need to do is call it from your ASP page with the relevant querystring values.

Instructions / Download


Download the zip file here: ClassicASPImageResizer.zip

Unzip the file to a folder on your server / local machine and run the default.asp for instructions and to see the code in action.

Credits


This solution was originally developed by Pieter Cooreman, QuickerSite (Classic ASP Website CMS). It was adapted and republished by David Barton, EasierThan Website Design.

The script is offered freely and no liability is accepted by either party for any issues arising from the downloading, installing or use of it.

If you find the script useful, backlinks and / or a beer (see original ASP Image Resizer page) would be much appreciated, but are not necessary.

48 comments:

  1. Awesome, but transparent PNG background saving as black. Any ideas?

    ReplyDelete
    Replies
    1. Not off the top of my head. Stuck on a project at the mo, but may get a look when time permits. Anyone else?

      Delete
    2. Thanks - just thought I'd let you know Pieter Cooreman has helped me out with the transparency-saving issue.

      Delete
    3. Good effort that man. I'll check out his updated solution in case I come across the same thing.

      Delete
    4. Where is it possible to find transparency saving issue update?

      Delete
    5. Hello Anon,

      I never got round to implementing them, but you can find some thoughts on Pieter Cooreman's (the author of the original) website.

      http://www.imageresizing.quickersite.com/

      Regards,
      Dave (not Anon)

      Delete
    6. Thanks for getting back to me, I can see on that link there is a maybe a png transaparency fix. I will give it a try, not too
      important for current project.
      Anyways, I thought I would help others by saving others hours off their life!!
      Im running windows 2008 / IIS7.5 and whilst using the demo zip provided works straight out of the box, when I implemented it against
      my image uploads folder, things fell over!
      I started getting really weird xml parser error? and image would not be displayed. Argghhh.

      Eventually after quite a few hours I discovered it boiled down to permissions on the uploaded image.
      If you http to the uploaded image, it would display fine in a browser, but when using Resize_Image.aspx called
      from an ASP page, it must use different permissions?. If I manually added READ permissions for the IIS_IUSRS account to the uploaded image,
      I noticed it worked!
      Without waffling more, the crux of the problem is if you use a PHP uploader to upload you image, php uploads the file to where ever
      upload_tmp_dir (PHP.ini) is pointing too, the default of this is usually C:\Windows\Temp, and then moves the file to the final upload
      folder you would have set up.
      Well it turns out that there is an issue with the PHP move, in that, once it has uploaded the file to upload_tmp_dir setting with OK
      permissions, when it carries out the move, it then looses the OK permissions, and then Resize_Image.aspx wont be able to read the image and
      falls over.
      People have mentioned creating a seperate upload folder, with added permissions, but I didnt not wont to do this as working on live system.
      Others mentioned adding specific permission to my default C:\Window\Temp, but again I did not want to mess about with permission on live box
      (ASP Code has been 95% running fine for 10+ years now)

      So the answer which finally worked for me was to change my php upload code, specifically the move section

      if(move_uploaded_file($_FILES['FileInput']['tmp_name'], $UploadDirectory.$NewFileName ))
      {
      }

      to now copy file instead, and then delete temp file after


      if(copy($_FILES['FileInput']['tmp_name'], $UploadDirectory.$NewFileName))
      {
      //now delete tmp file
      unlink($_FILES['FileInput']['tmp_name']);

      }

      The resuting copied file now has OK permisssions and Resize_Image.aspx reads this OK, no problems!!

      Hope this helps save someones sanity!

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. is it possible to resize images from another site that i have linked to my site

    currently when i put the full URL in it doesnt work.

    ReplyDelete
    Replies
    1. Hi Darryl,

      You need to add the following to the declarations at the top of the aspx page:

      <%@ Import Namespace="System.Net" %>

      Then replace the following lines of code:

      ' Prepare image
      Dim imgFullSize As System.Drawing.Image
      imgFullSize = System.Drawing.Image.FromFile(Server.MapPath(sInputURL))

      With these lines:

      ' Prepare image
      Dim imgFullSize As System.Drawing.Image
      If InStr(sInputURL, "http://") > 0 Then
      ' Attempt to get a remote image
      Dim imgWebRequest As System.Net.WebRequest
      Dim imgWebResponse As System.Net.WebResponse
      imgWebRequest = System.Net.WebRequest.Create(sInputURL)
      imgWebResponse = imgWebRequest.GetResponse()
      imgFullSize = System.Drawing.Image.FromStream(imgWebResponse.GetResponseStream())
      Else
      imgFullSize = System.Drawing.Image.FromFile(Server.MapPath(sInputURL))
      End If

      I haven't tested it thoroughly at this point, but it appears to work.

      Will add it to the demo when I get some spare time.

      Regards,
      Dave

      Delete
    2. thanks Dave thats prefect..what do you guys use for uploading... im trying to find a solution for uploading images, resizing and creating thumbnails... any solutions how there?

      Delete
    3. Hi Darryl,

      Glad it worked okay. We use the following free ASP uploader: http://www.freeaspupload.net

      You'll need to tinker to change the max file upload size and set the filename for saving. We call that, then call the image resizer and get it to output the uploaded file at a set location.

      As per comments in the resizer script, it is better if you can hard code the output file(s) to negate hacking opportunities.

      Hope that helps,
      Dave

      Delete
  4. Thank you SO much for sharing this! We've been using ASPjpeg component and now want to move to another server which doesn't have it installed. Your enhanced solution is excellent!!

    THANKS again!!!

    ReplyDelete
  5. Hi Dave, I've been searching the web for days looking for this and I finally found it, but now I get a 404 Page Not Found when trying to download it. :) Is there a new link for the download?

    ReplyDelete
    Replies
    1. Hi Anon,

      Sorry, just uploaded a new version of my website forget to include the zip file on it. Should be there now!

      Dave

      Delete
  6. Thanks for fixing the download link. I've been waiting all day to get to play with it. The resizing piece is working perfectly for me, but the saving isn't going so well can you tell me if this code looks correct and offer any causes to why the new file isn't getting saved?

    < img src="Image_Resize.aspx?ImgWd=70&IptFl=Photo_Gallery/Input.jpg&OptFl=Photo_Gallery/InputSmall.jpg&OptSc=N" />

    I uncommented the lines of code as suggested in the aspx file and I perform an upload of Input.jpg using freeaspupload and then attempt to resize the picture, but the InputSmall.jpg file is not getting created/saved even though the Input.jpg is there.

    ReplyDelete
    Replies
    1. A possible simple one. Have you renamed the aspx file? The default name is Resize_Image.aspx and you've used Image_Resize.aspx

      Delete
  7. yep, I did rename it as suggested in your comments :) I Have the problem narrowed down a bit. I have an asp page with a form that has the file selection. I submit the form and it calls the same page with does a check (if Request.ServerVariables("REQUEST_METHOD") <> "POST" then) to see if it needs to process the form or not. Any call to the aspx file when the Request_Method is equal to Post is ignored.

    ReplyDelete
    Replies
    1. Hi Anon,

      Have you tested the resize code works on a blank page without any of your code? It could be a permissions thing or .NET not enabled, but I wouldn't have thought so.

      Regards,
      Dave

      Delete
    2. ...or you are calling the script directly from the browser address bar so the HTTP_REFERER = "" and the condition is not met:
      If InStr(Request.ServerVariables("HTTP_REFERER"), Request.ServerVariables("HTTP_HOST")) > 0 Then...

      Delete
    3. Absolutely. The point of the HTTP_REFERER line is to prevent the script being called directly. After all, if you could do that, so could anyone else.

      Delete
  8. I placed a jpg on the server and put 2 calls in to resize the photo; one before the form submission and one after the submission. The one before the form submits works, but the one after does not.

    Code Steps:
    1. Page loads first time and takes path to just display the form (request method <> POST) Test file is resized.
    2. Form is submitted and takes the path to process the form (request method = POST) Test file is not resized.

    I tried putting the resize call at the top of the ProcessForm() function, but but still no luck or errors.

    ReplyDelete
    Replies
    1. Hi Anon,

      If our code works once, it should work every time. It would not care whether your ASP page has a form that has been POSTed or not. It is just an aspx page called as the source of an image. Provided the aspx page is called and the file to be resized is there, it should work.

      I think you may have to post some of your code for us to look at.

      Regards,
      Dave

      P.S. Why not add your name to say hello.

      Delete
  9. Hi Dave,
    I'm just now getting around to following up on this issue I posted on 10/18/2013 (originally as Anonymous). I was able to narrow down the problem but haven't been able to resolve the issue. It appears that I'm not able to delete the original file immediately after performing the resizing/saving.
    In the code below, I create 3 copies of the picture with varying sizes and then delete the original file. If I comment out the deletion of the original file (orgFile) then it all work perfectly, but if I don't, the original is deleted as expected, but none of the other files get saved.

    response.write "< img style='display:none;' src='g_imgResize.aspx?ImgWd=500&Ip-Fl=TestPhoto/" & orgFile & "&Op-Fl=TestPhoto/" & dbIFile & "&OptSc=N' />"

    response.write "< img style='display:none;' src='g_imgResize.aspx?ImgWd=70&Ip-Fl=TestPhoto/" & orgFile & "&Op-Fl=TestPhoto/" & dbTFile & "&OptSc=N' />"

    response.write "< img style='display:none;' src='g_imgResize.aspx?ImgWd=1600&Ip-Fl=TestPhoto/" & orgFile & "&Op-Fl=TestPhoto/" & dbFFile & "&OptSc=N' />"

    if objFSO.FileExists("TestPhoto/" & orgFile) then
    objFSO.DeleteFile "TestPhoto/" & orgFile
    end if

    I really don't want to leave the original files on the server since they could be fairly large. Any ideas?

    ReplyDelete
    Replies
    1. Hi Debug,

      I see now what the problem is. You're deleting the file before the scripts to resize are even run.

      Your ASP page is creating the HTML tag <img which will be executed by the browser when the page is sent to it. i.e. it is the client side browser that is forcing the resize using the ASPX file, not the server side ASP script.

      Before the page is returned to the browser though, you are deleting the uploaded file and therefore when the ASPX file is called by the browser, there is no file to resize.

      What you need to do is place your file deletion code in a next stage of your process, after you know the resized images have been created, perhaps when the use clicks 'Save' or similar.

      Hope thay makes sense.

      Regards,
      Dave

      Delete
  10. Thanks Dave, that makes total sense, and I probably should have seen that. I really appreciate your fast replies. The Classic ASP Image Resizer really is a great addition to my classic ASP library.

    ReplyDelete
    Replies
    1. No worries. Glad to help and to know there are still plenty of us about who are quite happy with good old ASP.

      Credit due to the original author, Pieter Cooreman, too!

      Delete
  11. Hi Dave, so far so good. Excellent work!!! I want to resize the images before I upload to the server. Any suggestions? I will appreciate if you have code where you have done it before. Thanks in advance.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Hi Julius,

      Can you explain what you mean? Do you mean during the upload process or locally on the user's machine?

      The first isn't possible with the code. The second would require you to be running IIS locally on the user's machine with the code installed there.

      Regards,
      Dave

      Delete
    3. Hi Dave, I meant before uploading to the server. I have seen some plugins such as the jquery file upload (jQuery File Upload Demo - blueimp) claim that they can resize the image on the client side before uploading to the server.

      Delete
    4. Hi Julius,

      In order to resize on the client side, you would need access to the client's hard drive? Is that what you're looking for?

      Can you explain what you're trying to do? Are your pages in Classic ASP?

      Dave

      Delete
  12. Hi Dave, yes my pages are in classic ASP. My customers typically upload all sizes of images both in bytes as well as dimensions. However I want to standardize the size of images on our website so I figured I could 1) limit the file size and 2) resize images before upload to a standard size say: 200px by 200px. The file size limit I can do however it is the resizing that I am more interested in.

    ReplyDelete
    Replies
    1. Hi Julius,

      That isn't something I've tried. Is there a reason you don't want the user to upload the file, such as anticipated size on upload?

      The solution in this post certainly can't be employed in that manner. I use a separate ASP script (http://www.freeaspupload.net) to upload the file and then use the solution in this post to resize it once it is on the server - where the aspx file can get at it.

      Anyone else out there used JQuery in this manner and care to advise?

      Cheers,
      Dave

      Delete
    2. Hi Dave,

      I have researched this issue thoroughly and agree the current solution can't do what I am looking for. I think it would require additional plugins like flash, silverlight, html5, google gears etc ...Thanks for the assistance. One further question ..... how do I get access to the fileData array values in classic ASP? I want to add a random number each time a customer uploads a new image however I need to get hold of the image/filename. I am also using freeaspupload so perhaps that will help.

      Thanks

      Delete
    3. Hi Julius,

      The FreeASPUpload site has an FAQ page including "How do I grab the filename of the uploaded file?" and "How do I rename the uploaded file?": http://www.freeaspupload.net/freeaspupload/faq.asp

      My own solution is a little more complicated. I edited Public Property Get FileName() within freeASPUpload.asp to assign the nameOfFile to my own global variable and then set FileName = to my own choice of temporary filename, in your case a random number.

      Public Property Get FileName()
      sMyGlobalVariable = nameOfFile
      FileName = "My_Filename.tmp"
      End Property

      Hope that helps.

      Regards,
      Dave

      Delete
  13. Hi Dave

    I dont know what is wrong. When i use script on localserver (on WinXP and on Win7 too) it is working, but it dont want to work on Win2008 server. Need I to set some parameters on IIS 7.5?
    Application pool is set to .NET Framework 2.0.50727, Classic Pipeline mode. I removed <%@ OutputCache Duration="600" VaryByParam="*" %>

    When i try to open showthumb.aspx link i take answer:
    404 - File or directory not found.


    I thing i was successfull to use it mounth ago, but not now :(

    Thanx a lot
    Michal

    ReplyDelete
    Replies
    1. Hi Michal,

      To my knowledge, it shouldn't require anything additional setting up in IIS and IIS 7.5 is fine, as is .NET 2.0 upwards. And I wouldn't have thought the pipeline mode would matter.

      A 404 is a specific server response to say the file is not there. Is it possible it is something simple like you have renamed Resize_Image.aspx file, but not in your code or vice versa?

      Regards,
      Dave

      Delete
  14. Nice thanks
    http://www.codingsack.com

    ReplyDelete
  15. Thanks for providing that great script! Your original version works fine but when i enter absolute paths for the script file and the images no resized image ist displayed. Any ideas? Thanks.
    Best Regards
    Olaf

    ReplyDelete
    Replies
    1. Hi Olaf,

      Without compromising security, can you be more specific as to what your absolute path is? i.e. Change some of the characters.

      First thing to check would be whether your server settings allow a script to create files in that directory.

      Best Regards,
      Dave

      Delete
  16. Hi Dave,
    problem solved - months ago :) Another Question: How can i resize and save an image in a folder on the server? Best Regards Olaf

    ReplyDelete
    Replies
    1. Hi Olaf,

      Glad you solved the original problem. Could you perhaps include details of how it was solved for the benefit of anyone else reading who may be having a similar difficulty?

      The enclosed ASPX file contains a list of possible querystring parameters and advice regards using them?

      To use the option to save a file onto the server, you need to uncomment the relevant lines in the ASPX file as per the instructions within it.

      If you've followed the instructions and it isn't working, can you provide an example of what you're trying to do, again altering actual paths slightly for security purposes?

      Best Regards,
      Dave

      Delete
  17. Hi,

    Any idea on how to make this work with filenames and paths with Swedish letters åäö?

    Thanks!

    /Martin

    ReplyDelete
    Replies
    1. Hi Martin,

      Can you specify what error or issue you're getting and where it occurs?

      Best Regards,
      Dave

      Delete
  18. I've implemented this with some modifications to stream the image from a varbinary column in SQL server. It works very well on my dev box, as well as our staging server. When I deployed it to production, images are all broken, and I see 302 errors in the developer console in chrome.

    When I try to navigate directly to the .aspx URL, I get redirected to the website root. I've checked every IIS setting I can think of and they are the same one all 3 servers.

    Any advise/thoughts/past experiences with something like this?

    ReplyDelete
    Replies
    1. Hi Unknown,

      Sounds like you have uncommented the section attempting to ensure the script is being called from its own server and in the instance of your production site, it isn't.

      But on your staging and dev boxes, maybe everything was on the same server?

      Hope that helps.

      Dave

      Delete