Amadiere.com

Fourteen and a half crazy frog burpers

15th March 2010

Good Quality Image Resizing in C#

Filed under: C# — Tags: , , , — Alex Holt @ 8:40 pm

I encountered a little bit of a problem the other day with some image resizing code from within an ASP.NET MVC application that was misbehaving. The issue was just a general C# and ASP.NET one, not related to MVC or Webforms, but it was that for some reason the images were losing a significant amount of quality when resizing. I’m talking a pixel sharp 2000 x 2000 picture that when resized to 300 x 300, was woefully blurry. Initially, the code was simply using the GetThumbnailImage() method to produce it’s resizes, this turned out to be the mistake!

While GetThumbnailImage() is fine for small thumbnail images (the clue I guess, was in the name), it somewhat struggled on the larger versions. To fix the issue, I had to convert the image to a bitmap, faff about with it like that, then export it back to a Jpeg once I was done.

For future me (and anyone else this might help), here is the code I eventually settled on:

EncoderParameters encodingParameters = new EncoderParameters(1);
encodingParameters.Param[0] = new EncoderParameter(Encoder.Quality, 90L); // Set the JPG Quality percentage to 90%.
 
ImageCodecInfo jpgEncoder = GetEncoderInfo("image/jpeg");
 
// Incoming! This is the original image. This line can effectively be anything, but in this example it's coming from a stream.
var image = Image.FromStream(new System.IO.MemoryStream(Picture));
 
// Creating two blank canvas. One that the original image is placed into, the other for the resized version.
Bitmap originalImage = new Bitmap(image);
Bitmap newImage = new Bitmap(originalImage, 300, (image.Height * 300 / image.Width));  // Width of 300 & maintain aspect ratio (let it be as high as it needs to be).
 
// We then do some funky voodoo with the newImage. Changing it to a graphic to allow us to set the HighQualityBilinear property and resize nicely.
Graphics g = Graphics.FromImage(newImage);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
 
var streamLarge = new System.IO.MemoryStream();
newImage.Save(streamLarge, jpgEncoder, encodingParameters);
 
// This is the line that returns the picture to the relevant part of the model.
_event.Picture = streamLarge.ToArray();
 
// No need for all that drama for the thumbnail, the loss of quality isn't noticable.
var thumbnail = image.GetThumbnailImage(80, (image.Height*80/image.Width), null, new IntPtr(0));
var streamThumbnail = new System.IO.MemoryStream();
 
thumbnail.Save(streamThumbnail, jpgEncoder, encodingParameters);
 _event.ThumbnailPicture = streamThumbnail.ToArray();
 
// Good boy's tidy-up after themselves! :O
originalImage.Dispose();
newImage.Dispose();
thumbnail.Dispose();
streamLarge.Dispose();
streamThumbnail.Dispose();

1st March 2010

4 Top Tips for portable ASP.NET MVC Apps

Filed under: ASP.NET,CSS,HTML,MVC — Tags: , , , — Alex Holt @ 10:22 pm

Loooong cat! :O

ASP.NET MVC is awesome (find out how awesome it is over dinner) and allows for some great applications to be made, quickly, while at the same time offering a high degree of maintainability over the code that is written. The danger with being able to do things too fast is that simple mistakes are sometimes made. These hopefully are nothing major, but can become an irritation at various points down the line. One of the things that occasionally gets left behind is the portability of code – and this can be a bit of a ‘damn I wish I’d done it like that to start with’ moment.

Below are a few hints that may (or may not) help you as you develop the next great slice of awesomeness.

Disclaimer: These tips are displayed as ASP.NET MVC tips, but in reality, some of them progress to general ASP.NET Websites and Applications – or just websites in general.

  1. Don’t Assume You Know Your Root
    Before I get started, let me give some background on this point. I have recently been doing some final tweaks to an otherwise great MVC application. However, one of the tweaks I did was to make sure that part of the system was securely done via HTTPS. When looking around the net, this appeared to be a lot trickier than I thought. After all, could all these people be wrong?:

    Basically, yes they can, but only because their articles are dated, not because they are fools (it should also be noted that although their articles may be dated, there are some good techniques and ideas in them, so worth a nosey). :) Bart Wullems does a good job of explaining the amazing simplicity of this new attribute that was added in MVC 2 Preview 2. I’m a little surprised as to how this maybe wasn’t given a little bit more publicity – its a useful tool that was sorely missing before. Behold, ye [RequiresHttps] attribute!

     [RequireHttps]
     public ActionResult Login()
     {
     return View();
     }

    This addition of SSL feather to my MVC Application’s bow was to prove too much for Visual Studio’s Cassini and I was forced onto my local IIS. This in itself wasn’t a great issue, but it highlighted some issues with the way the application had been developed. It had been assumed from the start that the application would live at the root of its own domain. This is true for the production version of the system and was for the large part true of the development system. When moving to IIS however, the project was set to run as a Virtual Directory – meaning the website root was no longer the same as the application root. Which lead me to trawl through the entire application tweaking things here and there, just to make it work no matter where it lived. Don’t assume you know were your application will live! It might be any number of little requirement changes that could cause you to have to rethink how you are building your application.

  2. Use ActionLinks for linking within your application
    Doing this will save you a bunch of time and is one of the core supported features of ASP.NET MVC, so why not use it when it’s so simple? There are so many good articles and posts on this, a great starting point is (as always) ScottGu’s, which part way down talks about Constructing Outgoing URLs from the Routing System

    <%=Html.ActionLink("View more details", new { Controller = "Products", Action = "Details", Id=42 })%>

  3. Url.Content for content that is URLs.
    Url.Content is to static content, what ActionLink is to your dynamic pages. If you have any Images, CSS, Script files or basically anything else that isn’t an MVC page, then this little beaut’ is for you! This allows you to negate any issues with website roots and application roots changing – without having to monitor and check any links!

    Before, you may simply have done:

    <img src="/lolcats/longcat.png" alt="To scale" />

    This would have worked until your application was moved from the webroot (Cassini) to a virtual directory (e.g. “/MVCApp” in IIS). If you do the following however, all is solved as it works out the URL and writes that out accordingly:

    <img src="<%=Url.Content("~/lolcats/longcat.png")%>" alt="To scale" />

    Would appear as the below, automagically:

    <img src="/MVCApp/lolcats/longcat.png" alt="To scale" />

  4. Relative links within your CSS
    This is something that isn’t specifically unique to MVC applications or ASP.NET in general. It’s more a good practice / make sure you are aware of guideline.
    When coding stylesheets, you’re often faced with wanted to add background-image’s to them. Without the server-side jiggery pokery that ASP.NET (and the like) allows, you are left with limited choices how to do this. But in reality, the solution is fairly simple. You need to fix two things: The location of your Images and the location of your CSS. It doesn’t really matter where they are, but just that they are fixed (or you have the patience to correct your links should you wish to restructure).

    Images from a CSS can be HTTP, absolute to the web-root or, as is awesome, relative to the CSS itself. This means that as long as all your styles are entirely located within your stylesheet’s and not intermingled with your code, you’re on to a winner. It doesn’t matter which page calls the CSS, whether it be your homepage or one that is 42 levels deep – the links are only ever relative to the CSS page (which you included via Url.Content, right, eh? yeah!?).

    In the following example, the CSS is located within a ‘Styles’ directory directly at the project root.

    .longCat
    {
     background-image: url('../lolcats/longcat.png');
    }

Hopefully these pointers will help someone else, if not, they will hopefully protect against my own stupidity and making similar mistakes again. Feel free to comment below if there are any more thoughts and portability ideas you think I could do with including.

9th November 2009

BEHOLD! The coming of ASP.NET 4.0!

Filed under: ASP.NET,C#,MVC — Tags: , , — Alex Holt @ 8:30 pm

‘Tis a day of reconing upon us! The mighty that hath enjoyed the fruits of our labour shall become our lesser kin. ASP.NET#3.5 is being bumped up A WHOLE HALF VERSION! When you’ve regained your breath (have a cup of tea, if it helps) – read on for a breakdown of the glory that shall shine bright in all that is sparky, shiny and new!

First, for me, the major feature has to be something that is already available: ASP.NET MVC – now part of the ‘Out Of The Box’ experience and no longer required to be a separate download (though, still will be for ASP.NET 3.5). This in itself is worthy of a good cold shower, but get this… it’s version 2! Oh yeah, sweetness itself.

MVC 2.0 isn’t actually available as a release version at the moment and is in fact just a preview version. However, well worthy of look if you are at all interested in the original MVC. If you’ve been unable to see the new features in 2.0, then I seriously do not understand how you can sleep at night. In my bid to cure your insomnia, here are a few of the highlights, though, I could go on!

  • Areas are being introduced to allow you to easily spread your code apart into logical parts. E.g. You can have an area for your User / Account management stuff, and an area for your Product Listings. This allows you to keep the MVC pattern but in segmented way. Your User Area would have a directory for Controllers, Models and Views, and your Product Area would have separate areas too.
  • DataAnnotation Validation is voodoo. A black magic that makes you sit back and go: “WTF, is that it”? It allows you to declare the requirements of a field in a single place within your application, then any time something attempts to update it, the validation must be passed.
  • Default Values are easier to declare now.
    // something old
    public ActionResult Browse(string category, [DefaultValue(1)] int page)
    {
    }
    // something new
    public ActionResult Browse(string category, int page = 1)
    {
    }
  • They have shortened the attribute [HttpPost] . I know, I saved the best until last!
    // out with the old
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(Product product)
    {
    }
    // in with the new!
    [HttpPost]
    public ActionResult Create(Product product)
    {
    }

As for the rest of ASP.NET 4.0, what can you look forward to? Well!

  • The superbly sweet…
    <%:productDescription%>

    Did you see it? The shorthand response.write alternative which was the equals sign has a rival. But not a dark nemesis with fire-breathing tentacles, nope, a bright white halo-toting angel rival. Simply replace the equal sign with a colon and you have a HTML Encoded Response.Write alternative. Finally, what seems to be a simple solution to reduce considerably, the risk of XSS attacks.

  • URL Routing (or of course, URL Rowwting if you are from the US) in much the same way that MVC has it. If you’re familiar with MVC 1, you’ll know the awesomeness that is the friendly URLs that they can produce. With ASP.NET4, this gesture is extended to the general Webforms environment.
  • Auto-Starting Web Applications are here! No longer do you need to set up a cron job to make sure that a random visitor doesn’t have to wait for 20 seconds while your application reloads itself into memory. A few tweaks and bliss is yours (and your customers).
  • Web.config has been on a diet. It’s shredded almost all of its weight. The only things that need to appear within this now are config settings that you actually want to change from their default. Genius!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
      </system.webServer>
    </configuration>
  • The Entity Framework has become so awesome, it’s skipped a version or two to become EF4.0, and some of the upgrades make it strong and compelling contender for your model structuring! It contains considerably less suck than the first version.

All this ‘win’ makes you nervous? How can the world not implode? That my friend, I do not know – I think it may be like the Y2K Doomsday predictions – its the .NET4 DOOM! Either way, it’s looking good in the ASP.NET world at the moment and I can’t wait for it to land on my desktop!

Older Posts »

Theme designed & built for Amadiere.com by Alex Holt. Powered by WordPress