I needed a GetThumbnail method which kept the aspect ratio of the original and also scaled the image with decent quality. There are several ways you can do this, I got a few examples here.
First, there is the Image.GetThumbnailImage() method which is pretty good if you just want to scale down the original image to a specific size, say 64 x 64:
thumbnail = img.GetThumbnailImage(64, 64, Nothing, IntPtr.Zero)
But the problem with this method is the image get scewed and most people I think want to keep the aspect ratio. So if I want to scale down the original image by, say by 50%, and still keep the aspect ratio:
Private Function GetAspectRatioThumbnail(ByVal img As Image, ByVal percent As Integer) As Image
Dim ratio As Double = percent / 100
Return img.GetThumbnailImage(img.Width * ratio, img.Height * ratio, Nothing, IntPtr.Zero)
Very simple, yes, but if you've not been doing image manipulation before this could get you going I guess.
Now, I needed to fit a big image with unknown size into a fixed size area in a report, and this image area in the report streches the image to fit the bounds by itself. Not good. So I needed to both scale down the image, and "pad" it so it filled out the image area in the report. This little method helped me out here:
Private Function GetPaddedAspectRatioThumbnail(ByVal img As Image, ByVal newSize As Size) As Image
Dim thumb As New Bitmap(newSize.Width, newSize.Height)
Dim ratio As Double
If img.Width > img.Height Then
ratio = newSize.Width / img.Width
ratio = newSize.Height / img.Height
Using g As Graphics = Graphics.FromImage(thumb)
'if you want to tweak the quality of the drawing...
g.InterpolationMode = InterpolationMode.HighQualityBicubic
g.SmoothingMode = SmoothingMode.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality
g.CompositingQuality = CompositingQuality.HighQuality
g.DrawImage(img, 0, 0, CInt(img.Width * ratio), CInt(img.Height * ratio))
You can tweek the quality of the image drawing as you see fit, it all depends on the size of the image, how much you need to scale it down and so on. I'm sure there are many other ways to do this, but it works for me.
More than a week old news, but this is a book I'll be getting when it comes out. Fritz Onion writes on his blog
My production editor at Addison Wesley just informed me that Essential ASP.NET 2.0 just went to press last week! I should have copies in my hand before Halloween, just in time to bring with me to TechEd Developers in Barcelona (where they should also be available at the conference bookstore, assuming everything is shipped successfully). If you won't be in Barcelona, you can also pre-order it from Amazon, Barnes and Noble, or Bookpool.com of course ;)
I'll see if I can pre-order it where I usually buy books like this...
Shreeraj Shah on Top 10 Web 2.0 Attack Vectors
This technological transformation is bringing in new security concerns and attack vectors into existence. Yamanner, Samy and Spaceflash type worms are exploiting “client-side” AJAX frameworks, providing new avenues of attack and compromising some of the confidential information.
Worth reading I say. Especially #6, Client side validation in AJAX routines:
WEB 2.0 based applications use AJAX routines to do a lot of work on the client-side, such as client-side validations for data type, content-checking, date fields, etc. Normally, these client-side checks must be backed up by server-side checks as well. Most developers fail to do so; their reasoning being the assumption that validation is taken care of in AJAX routines. It is possible to bypass AJAX-based validations and to make POST or GET requests directly to the application – a major source for input validation based attacks such as SQL injection, LDAP injection, etc. that can compromise a Web application’s key resources.
Well, that happened to me today, and even though I've been working with Win 2k3 for quite some time now, not seeing the application pools where they were supposed to be quite baffled me :)
Of course the simple answer is that IIS was running in IIS 5.0 Isolation Mode (also called IIS 5.0 compatibility mode). Not sure why though, but I guess there may have been some issues with old COM components or something and therefore the default IIS settings were changed.
If you want to change back to "Worker Process Isolation Mode"? Just (quoted from TechNet):
1. In IIS Manager, expand the local computer, right-click Web Sites, and then click Properties.
2. Click the Service tab, clear the Run WWW service in IIS 5.0 isolation mode check box, and then click OK.
3. To start the WWW service, click Yes when asked if you want to restart IIS now.
If the switch to worker process isolation mode is successful, a folder named Application Pools appears in the IIS Manager listing for your local computer. You can quickly determine which isolation mode IIS is running because the Application Pools folder is present in worker process isolation mode and absent in IIS 5.0 isolation mode.
Saving an Image object to disk is straight forward, just call the Image.Save(filname) method and it's done. But what if you need to save that Image to a Byte() array (or Byte in c# speak ;) because you need to store it in a database or stream it somewhere? It turned out to be quite simple if you use the MemoryStream class of .NET and the Image.Save(stream, imagetype) method overload:
Dim img As Image = LoadImageSomehow()
Dim rawData() AsByte
Using ms AsNew MemoryStream()
rawData = ms.GetBuffer()
'do something with the rawData buffer here...
Works for me.