Resize image on the fly with ASP.NET MVC

I built a piece of code sometime ago and today I decided to optimize it.

My use case is this: a user can upload some photos of his house for example. Image dimensions (height x width) are not restricted. The user can upload any photo as long as its size is less than or equal to 750 KB.

Then, I have a listing page (Index.cshtml) that has a WebGrid. The grid shows realties available for sell, rent, etc. In this grid I want to display just a thumbnail of a given photo (the first one I grab as per code bellow) for each realty. I placed a constraint such that the thumbnail dimensions must be 100x100 pixels. Of course one shouldn’t load the full size version of a photo just to show it on the grid. The grid has 10 rows per page and if the images are on the range of 500 KB, the load put on the user connection to transmit all those photos from the server to the client would be high: 10 x 500 KB ≃ 5 MB. This would be an unresponsive page! No doubt…

Googling a little bit I stumbled upon something I didn’t know yet. It’s called WebImage and comes in System.Web.Helpers just as the WebGrid I discussed earlier. With this little kid on the block, one can have a controller “action” that does something like this:

public void GetPhotoThumbnail(int realtyId)
{
// Loading photos’ info from database for specific Realty...
var photos = DocumentSession.Query<File>().Where(f => f.RealtyId == realtyId); if (photos.Any()) { var photo = photos.First(); new WebImage(photo.Path) .Resize(101, 101, false, true) // Resizing the image to 100x100 px on the fly... .Crop(1, 1) // Cropping it to remove 1px border at top and left sides (bug in WebImage) .Write(); } // Loading a default photo for realties that don't have a Photo new WebImage(HostingEnvironment.MapPath(@"~/Content/images/no-photo100x100.png")).Write(); }
Calling the .Write() method does the magic. As you can see, I’m not saving the thumbnail in the disk, that is, a new image is generated on the fly/dynamically and sent to the user’s browser. Amazing…
In a view using the Razor syntax one would have something like this to display the photo:
<img src="@Url.Action("GetPhotoThumbnail", new { realtyId = item.Id })" width="100" height="100"/>
Another useful variation/overload of the above action method is this one (even more dynamic):
public void GetPhotoThumbnail(int realtyId, int width, int height)
{
    // Loading photos’ info from database for specific Realty...
    var photos = DocumentSession.Query<File>().Where(f => f.RealtyId == realtyId);

    if (photos.Any())
    {
        var photo = photos.First();

        new WebImage(photo.Path)
            .Resize(width, height, false, true) // Resizing the image to 100x100 px on the fly...
            .Crop(1, 1) // Cropping it to remove 1px border at top and left sides (bug in WebImage)
            .Write();
    }

    // Loading a default photo for realties that don't have a Photo
        new WebImage(HostingEnvironment.MapPath(@"~/Content/images/no-photo100x100.png")).Write();
}
Then, in the view one would call the action passing the width and height variables as per requirement:
<img src="@Url.Action("GetPhotoThumbnail", new { realtyId = item.Id, width = 100, height = 100 })" />
There are a handful of available functions in a WebImage. You should really check them out.

You can find more insightful info about the WebImage class reading this post by Gunnar Peipman: ASP.NET MVC 3 Beta: Simple image manipulations using WebImage helper

Note: there really are better ways of handling this kind of situation (adding image caching, etc – see ImageResizer) but for the site I’m working on, the solution I show in this post is sufficient and pretty responsive right now.

Hope it helps.

Hide table column and colorize rows based on value with jQuery

This is a handy piece of code that I used last year in one of my projects. I had scheduled to post it but it was just after I saw this question at StackOverflow that I decided to write about it. So here it is…

Let’s say you want a nice UI experience and to achieve that you wanna colorize/highlight a table row according to a given value present in a column of this row.
This is a simple task when we use jQuery.

I use the WebGrid that comes with ASP.NET MVC to display data on a web page using an HTML <table> element. It’s available in the namespace System.Web.Helpers. The approach described in this post is useful not only with the WebGrid but with any framework/language you use to output HTML code since the manipulation is done on the client side with jQuery.

Take this screen as an example:

HTML table with last column Active to be hidden displaying values Yes and NoFigure 1 - HTML table with last column Active to be hidden displaying values Yes and No

We want hide the last column “Active” and color the row which has a value Yes in this same column.

The above statement can be accomplished with the following code:

(function ($)
{ hideColumnColorRow = function (column)
{ $(
'td:nth-child(' + column + '),th:nth-child( ' + column + ')').hide(); $('tr').find('td:nth-child(' + column + '):contains(Yes)').parent().css('backgroundColor', 'LightGreen'); // Could be an hexadecimal value as #EE3B3B };
})(jQuery);

The hideColumnColorRow function* takes the column number as a parameter. It hides the column <td> and its header <th> using jQuery’s supper useful nth-child selector. Then for each table row <tr> it traverses the row’s columns and looks at the value of each column using :contains selector. If it finds a value = ‘Yes’ it’ll assign a background color to the column’s parent, that in this case is the <tr> (the row) using its CSS backgroundColor property.

So, taking Figure 1 as an example, the above code can be used in an ASP.NET MVC view this way:

<script type="text/javascript">

    $(document).ready(function ()
{
hideColumnColorRow(5); // Hiding the 5th column and colorizing the row for which this column has a value = Yes
});
</script>

* I’ve placed the jQuery/JavaScript function inside a file named custom.js. It resides inside the Scripts folder of the sample app available here. There’s no need to reference this script file in the view page because with the introduction of ASP.NET 4.5 we now have an all new Bundling and Minification Support for CSS and JavaScript files.

When the the app is run, this is the result:

HTML table with column Active hidden and highlighted rows based on its valueFigure 2 - HTML table with column Active hidden and highlighted rows based on its value

This is a really interesting requirement that one can implement in no time thanks to the power of jQuery. jQuery is one of the most fascinating things when we talk about software development. Its creator “John Resig” should be awarded a Computer Science Nobel Prize if that existed. Well it could be the Turing Award.

Anyone should take a look at jQuery and start using it as early as possible. It’s a must have today. I simply love it! Coração vermelho

Source code
I’ve put together a sample ASP.NET MVC 4 (uses NET Framework 4.5) so that you can try this out. You can run the app using the recently launched Visual Studio 11 Beta. You can download the free Visual Studio 11 Express Beta for Web here and the app code here.

Hope it helps.

Installing Brazilian Portuguese dict. in Sublime Text 2

Today I downloaded one more dictionary to use with Sublime Text 2. Sublime Text is a multipurpose text and code editor. So far the best IMHO. I want to spell check my Portuguese texts of course. I followed the instructions described here to grab an additional dictionary.

From that page we have that:

Sublime Text uses Hunspell for its spell checking support. Additional dictionaries can be obtained from the OpenOffice.org Extension List

I then headed to OpenOffice.org to search for a pt-BR dictionary. I found it and then when I downloaded it from http://extensions.services.openoffice.org/en/project/Vero I got a file with a different extension (.oxt) of that used by Sublime Text 2. More on this bellow…

The file name is Vero_pt_BR_V208AOC.oxt.

Using Mac OS I tried to place this file inside this folder

/Users/leniel/Library/Application Support/Sublime Text 2/Packages/User

following the instructions given by Sublime Text 2 doc.

Closed Sublime Text 2 and reopened it. Went to the menu View > Dictionary and the new dictionary wasn’t there.

Well, something is plain wrong here. The already installed dictionaries that come with Sublime Text are present in this folder:

/Users/leniel/Library/Application Support/Sublime Text 2/Packages/Language - English/

Inside the above folder there are two English dictionaries with file extensions: .aff and .dic.

A little bit more thinking and I tried what could do the trick. I renamed the downloaded dictionary file from Vero_pt_BR_V208AOC.oxt to Vero_pt_BR_V208AOC.rar. Opened the compressed file and to my surprise there they were… extracted the files pt_BR.aff and pt_BR.dic. Easy as pie.

It turns out the .oxt file is just a wrapper…

I renamed the folder Language – English to just Languages and placed the files pt_BR.aff and pt_BR.dic in this folder. Closed Sublime Text 2 and reopened it. The new dictionary appeared:

Sublime Text 2 Dictionary menu option listing the pt_BR dictionary just addedFigure 1 - Sublime Text 2 Dictionary menu option listing the pt_BR dictionary just added

Hope it helps.

Export list of used NuGet packages for a given project

This one is as simple as the title says… I just wanted to get a list of all NuGet packages I’m currently using in my ASP.NET MVC 4 project.

If you look at the NuGet Package Manager window that you can access by right clicking a project in Solution Explorer and then selecting Manage NuGet Packages… you’ll see that there’s an Installed packages option on the left vertical menu. This is good and all but the manager doesn’t have an option to export the list of installed packages to a simple .txt file.

NuGet Package Manager listing Installed Packages for the projectFigure 1 - NuGet Package Manager listing Installed Packages for the project

One interesting thing is that NuGet uses a .XML file called packages.config that resides in the root folder of every project to actually fill the above window. Every time you add or delete a NuGet package this file is updated to reflect the changes.

This is the content of my packages.config file:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="AttributeRouting" version="1.5.4426" />
  <package id="DataAnnotationsExtensions" version="1.0.1" />
  <package id="DataAnnotationsExtensions.MVC3" version="1.0.1" />
  <package id="jQuery" version="1.7.1" />
  <package id="jQuery.Ajax.Unobtrusive" version="1.0" />
  <package id="jQuery.UI.Combined" version="1.8.17" />
  <package id="jQuery.Validation" version="1.8" />
  <package id="jQuery.Validation.Unobtrusive" version="1.0" />
  <package id="jquery-globalize" version="0.1.0" />
  <package id="knockoutjs" version="1.2.9.0" />
  <package id="log4net" version="1.2.10" />
  <package id="Microsoft.Web.Optimization" version="0.1" />
  <package id="microsoft-web-helpers" version="1.15" />
  <package id="Modernizr" version="2.0.6" />
  <package id="MvcSiteMapProvider" version="3.2.1.0" />
  <package id="Newtonsoft.Json" version="4.0.8" />
  <package id="NLog" version="2.0.0.2000" />
  <package id="RavenDB-Embedded" version="1.0.700" />
  <package id="System.Web.Providers" version="1.0.1" />
  <package id="T4MVC" version="2.7.0" />
  <package id="WebActivator" version="1.2.0.0" />
</packages>

This file serves the purpose of this post but it’d be a nice addition to the NuGet manager if it had a button to export the list of installed packages in a better formatted way. Just an idea.

Just let me take the opportunity to say “I Love You NuGet”. You let me explore the plethora of knowledge of fellow developers scattered all over the world in an easy way with the push of a button. I have no better words to describe you! You contribute enormously to the world development. Keep evolving!

Apple’s magic mouse & wireless keyboard battery life

I’ve been collecting data regarding the battery life cycle of my Apple’s magic mouse and wireless keyboard. I thought it’d be good to post this data here so that you dear reader can draw your own conclusions about how long should the battery life last.

Apple Magic Mouse ($ 69 or R$ 229 today)Apple Wireless Keyboard ($ 69 or R$ 229 today)

This is interesting data to look at because I like statistics and it’s good to analyze data. It helps you predict what to expect… Obviously the batteries’ lifespan changes according to how much time you spend using these devices. In my case I tend to use the computer 8 hours/day on average.

Just now I decided to search for a neat app ( Finch for Mac ) so that I can track the time I pass working on the computer. This will for sure give me more accurate data in the near future. For now I’ll have to take this data for granted…

Take a look at the following Google spreadsheet:

As you see the keyboard has a great autonomy and there were periods in which I didn’t work as much as I’d like on the computer because the mouse charges used to last 3 weeks. This denotes periods of inactivity. Now that I’m doing more intensive work the mouse battery lasts only 1.5 weeks. This is half the time previously taken to drain the battery.

For the record: I also own an Apple’s battery charger. Recharging the batteries is an easy task. Once more I’m contributing to the environment.

Apple Battery Charger ($ 29 today)

All these Apple devices are great IMHO as it’s the case with everything made by Apple!

The only “complaint” is that I think the mouse should have a greater autonomy. Maybe this will be the case with more recent technology iterations.

Blogger dynamic views with Undocked Gadgets bar

Blogger recently launched gadgets support for dynamic views. This is really cool and was a missing piece to go with dynamic views.

One of the things that I really didn’t like about the gadget bar is that it’s hidden (docked) in the right side of the window. It’s difficult to see and so I Googled about an undocked version but couldn’t find it.

Blogger docked gadgets sidebar (barely visible) or could we say hidden?Figure 1 - Blogger docked gadgets sidebar (barely visible) or could we say hidden?

Here I show you how to get an undocked version so that your visitors can enjoy the gadgets bar in its full glory. Follow these simple steps:

1 - Select the Template option at draft.blogger.com

2 - Click the Customize button

3 - In the Window that opens select Advanced

4 - Select Add CSS

5 - Copy & paste the following piece of code in the Add custom CSS field

#gadget-dock
{
    right: 0;
}

6 - Click Apply to blog button in the window top right corner

You won’t see the change applied immediately.

Now go and open your blog and you should see an undocked gadgets bar!

Blogger undocked gadgets sidebar (now visible)Figure 2 - Blogger undocked gadgets sidebar (now visible)

I hope blogger gives the option to customize this without the need for CSS code. It’ll be easier for its users and will provide a better experience for blog’s visitors… Alegre

EDIT

To answer Hannah’s question: if you also want to customize the background colors of the gadgets bar, you can apply these styles following the same procedure described above:

.gadget-icons
{
    background-color: red;
}

.gadget-title
{
    background-color: red;
}
.gadget-selected .gadget-icons
{
    background-color: yellow;
}

One thing to remember here is that as the gadgets’ icons are white you must choose a background color that’s not too much whitish.

Play with the colors and enjoy!

Listing compressed files within a .zip or .rar by file size

I'd like to know any app that shows a list of the files that lie within a compressed file .zip or .rar. If the list could be ordered by file size it'd be great! It could be any software that runs on Windows or Mac OS since I use both OS using Parallels.

Why this is important to me?
The answer is that sometimes I need to send a compressed file to someone and this file generally contains lots of coding files that are part of a Visual Studio Solution/Project for example. I just want to send a subset of those files. There are some big files like DLLs and database files scattered everywhere in a lot of folders that don’t need to go with the compressed file.

So how can I avoid spending time going through all those folders/files, looking their size and deleting one by one to make the final compressed file to be uploaded smaller?

I thought about asking this question at SuperUser. To tell the truth I already had the question typed there but before I could post it and after a few tries by myself I got what I wanted using WinRAR with an easy play of menu commands. So how can you do this? Follow me…

1 - If you don’t know or don’t have WinRAR or use another file archiver, you can get it at:
http://www.rarlab.com/download.htm

I use WinRAR in its evaluation copy incarnation that once in while pops up a dialog asking you to purchase it. Smiley surpreso It works great even if you don’t want to purchase it… take it easy.

2 - At first compress the folders and files you want without getting bothered about the size of the resulting compressed file. After installing WinRAR it’s available in the context menu of any file or folder in Windows Explorer.

3 - Open the compressed file in WinRAR and play with the menu just a little bit. Go to the Options | File list and select Flat folders view and Details menu options.

WinRAR listing the files of a compressed file (trunk.rar) by file size
Figure 1 - WinRAR listing the files of a compressed file (trunk.rar) by file size

Taking the above screenshot into consideration (it lists the content of a trunk project folder compressed), we can see that it has 1554 folders and 1624 files. This compressed file alone has 87 MB in disk when the actual uncompressed content has 193 MB in size but it’s still pretty big to send it over the wire… I have a lot of folders and files to go through if I want to delete the big and unnecessary files to try to decrease the final size! As you see, it also contains many duplicate files in different paths… it’s pretty daunting just to think about a manual scan. A visual scan in a single screen is much better. How do you get a big picture of this compressed file?

4 - Order all the files by size by clicking the size column header.

5 - Select all the files you want to remove/delete from the compressed file in just one go. One can do this in two different ways: clicking a file and holding the ctrl key and clicking another file to select not contiguous files OR selecting one file and pressing the shift key and clicking another file to select contiguous files. After this it’s just a matter of right clicking the file selection and executing the Delete files command.

Hope this useful tip helps you someday!