High quality dynamically resized images with .net

Image Resize

A lot of web sites make use of code which dynamically resizes images. This technique is great for producing thumbnails on the fly. In fact, I used it for the listing pages of this blog. I was a little disappointed with the quality. The image looked blurred and I could often see dithering or compression artefacts. While working on another project I have spent some time researching how you can increase image quality while resizing with .Net.

.Net provides a of set easy to use image manipulation classes called System.Drawing (GDI+). The default settings for these classes are based on speed not quality. There are many examples on the web of how to resize images using these classes, but most of them produce low quality images. The most basic example would have the following code.

System.IO.MemoryStream memoryStream = new System.IO.MemoryStream( byteArray );
System.Drawing.Image image = System.Drawing.Image.FromStream( memoryStream );
System.Drawing.Image thumbnail = new Bitmap(newWidth, newHeight);
System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage( thumbnail );
graphic.DrawImage(image, 0, 0, newWidth, newHeight);                
thumbnail.Save(Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg);

You start with a byte array which contains the image data loaded from either a database or file. You then resize the bitmap using a number of System.Drawing methods and finally save the bitmap to an output stream. In this case the output stream is the Response output stream. The first improvement is to include a quality setting for the JPEG compression.

System.Drawing.Imaging.ImageCodecInfo [] Info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();    
System.Drawing.Imaging.EncoderParameters Params = new System.Drawing.Imaging.EncoderParameters(1);
Params.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
Response.ContentType = Info[1].MimeType;
thumbnail.Save(Response.OutputStream,Info[1],Params);

Major benefits can be gained by resetting the Graphic object properties to use the most effective algorithms. The InterpolationMode especially effects resizing, the others are useful for when you are using any compositing methods. As we are using the DrawImage method which is a compositing method you should include all four properties.

graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;

By default, .Net will utilize a web-safe palette when converting a bitmap to an image suitable for a web page. The result is that most gif files created using the above code would produce badly dithered images. Morgan Skinner wrote a fantastic article “Optimizing Color Quantization for ASP.NET Images” on how to create the optimal palettes for gif output. If you wish to output gif files you should include his code in your project and modify your code to fork when creating gif or jpeg output.

System.IO.MemoryStream memoryStream = new System.IO.MemoryStream( byteArray );
System.Drawing.Image image = System.Drawing.Image.FromStream( memoryStream );
System.Drawing.Image thumbnail = new Bitmap( newWidth, newHeight );
System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage( thumbnail );

graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;

graphic.DrawImage(image, 0, 0, newWidth, newHeight);                

if( contentType == "image/gif" )
{
    using ( thumbnail )
    {
        OctreeQuantizer quantizer = new OctreeQuantizer ( 255 , 8 ) ;
        using ( Bitmap quantized = quantizer.Quantize ( bitmap ) )
        {
            Response.ContentType = "image/gif";
            quantized.Save ( Response.OutputStream , ImageFormat.Gif ) ;
        }
    }
}


if(  contentType == "image/jpeg" )
{
    info = ImageCodecInfo.GetImageEncoders();
    EncoderParameters encoderParameters;
    encoderParameters = new EncoderParameters(1);
    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
    Response.ContentType = "image/jpeg";
    thumbnail.Save(Response.OutputStream, info[1], encoderParameters);
}

All this additional processing can add load time. On commercial sites the developers at my company often build-in a caching mechanism for commonly requested sizes.

Although System.Drawing provides a GetThumbnailImage method it only works well when the requested thumbnail image has a size of about 120 x 120 pixels. If you request a large thumbnail image, there could be a noticeable loss of quality. This function also searches for thumbnails stored in the image data which can cause problems if the original was generated with a digital camera. Because of these issues I use the DrawImage method.

Published 26 October 2005 21:38

Comments

1 David
This is exactly what I was looking for - thanks a lot! (By the way your site is very nicely designed and built)
Posted 13 December 2005 13:44

2 pravin
Thanks. helped me a lot :-)
Posted 09 January 2006 07:19

3 Bill Winder
Thank you this article helped me lots with my web imaging application. You saved me alot of time.
Posted 09 January 2006 08:58

4 bhattji
Hi, Really a nice explanation. We have been using Thumbnail.aspx page with this sort of code. Can you provide a sample Thumbnail.aspx file ?
Posted 10 February 2006 06:25

5 Glenn
@bhattji, Thanks for your comment. All the code I have is wrap up in a large framework I use. I will try and put together a download example, but it could be a long time before I can get around to it.
Posted 14 February 2006 14:23

6 Phil
Thanks for your write up - this is exactly the info I was looking for. I was beginning to give up hope in .NETs ability to produce quality images!
Posted 11 April 2006 03:01

7 Murray
This was perfect. I found this page straight from a Google search, and it was exactly what I was looking for. Thanks very much!
Posted 19 April 2006 18:20

8 Ben
Glenn,

I can't thank you enough. I am designing my first web site (as a hobby) and have had a great time picking up tips on the web. This is by far one of the most valuable ones I have learned so far. Who wants to upload their pictures to a site if they are going to look crappy? Thanks to you mine are now crystal clear!

Posted 28 April 2006 04:35

9 Rob
Well done - big cake for you!!
Posted 05 May 2006 06:17

10 Iulia Stoian
Good article; I need a solution for drawing a table (jpeg) non modifiable format using lines, rectangles and text (data from database); I need to have proper Preview and also a Print (high quality). If I set resolotion to (72,72) the Preview will no be legible, for higher res. the image size will increase; also how can I print the same image to a printer at at least 200 resolution? Is there a solution for this? any answer or reference to articles will be greatly appreciated. Regards.
Posted 05 May 2006 15:44

11 Glenn Jones
@Lulia. A bitmap may not be your best option if legibility at 72 dpi resolution is an issue. I would re-evaluate using bitmaps altogether. If you do want to use bitmaps then you could consider tiling them into a scrolling area like Google maps. If printing is foremost PDF may be a better format.
Posted 09 May 2006 11:43

12 Santosh Kumar RSPL
Really it's wonderfull article. I read so many article for resize image dynamically, but found this one as most usefull. I got what I was exactlly looking. But if you convert image into png format instead of jpeg it looks too good compare to png. Thanks a lot :-)
Posted 10 May 2006 12:06

13 Syed Ibrahim
its really useful for me.
Posted 17 May 2006 15:55

14 Manjit dahiya
it is very nice .but the image generated from this code still require some improvements thanks
Posted 03 June 2006 06:15

15 uspomena
Thanks for the explenation it seems like many got a benefit of this writing except me. I still do not know how everythning works and how to resize a picture without loosing the quality...
Posted 14 June 2006 23:43

16 Ettienne
WOW!
Thanks so much...
I was working with the quantize samples on the MSDN site and what a mission....

This sort everything out wham bam...
Here is my thumbnail generator exmaple in VB with above applied...
Still a little messy but im sure it will help.....

<%@ Page Language="vb" AutoEventWireup="true" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<%@ import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.Drawing.Text" %>
<%@ Import Namespace="System.Drawing.Drawing2D" %>

  Sub Page_Load(Sender As Object, E As EventArgs)
        Dim originalimg, thumb As System.Drawing.Image
        Dim FileName As String
        Dim inp As New IntPtr()
        Dim width, height As Integer
        Dim rootpath As String
        rootpath = ConfigurationSettings.AppSettings("site_path")
        FileName = rootpath & Request.QueryString("FileName") '
        Try
            originalimg = originalimg.FromFile(FileName) ' Fetch User Filename
			IF Request.Querystring("height") = "" THEN 
				height = originalimg.height
			ELSE
				height = Request.Querystring("height")
			END IF
			
			IF Request.Querystring("width") = "" THEN 
				width = originalimg.width
			ELSE
				width = Request.Querystring("width")
            End If
            
            Response.ContentType = "image/jpeg"
            thumb = Ettienne_Thumbnail(originalimg, height, width)
            Dim codecEncoder As ImageCodecInfo = GetEncoder("image/jpeg")
            Dim quality As Integer = 100
            Dim encodeParams As New EncoderParameters(1)
            Dim qualityParam As New EncoderParameter(Imaging.Encoder.Quality, quality)
            encodeParams.Param(0) = qualityParam
            thumb.Save(Response.OutputStream, codecEncoder, encodeParams)

			originalimg.Dispose()
            thumb.Dispose()
            Response.End()
        Catch
			Dim objBMP As System.Drawing.Bitmap = New Bitmap(110,110)
			Dim objGraphics   As System.Drawing.Graphics
			objGraphics = System.Drawing.Graphics.FromImage(objBMP)
			objGraphics.Clear(Color.Red)
			Dim objFont As System.Drawing.Font = New Font("Arial", 16, FontStyle.Bold)
			objGraphics.DrawString("No Image", objFont, Brushes.White,3, 40)
			Response.ContentType = "image/GIF"
			objBMP.Save(Response.OutputStream, ImageFormat.Gif)

			' Kill our objects
			objFont.Dispose()
			objGraphics.Dispose()
			objBMP.Dispose()
        End Try
    End Sub
    Function GetEncoder(ByVal mimeType As String) As ImageCodecInfo
        Dim codecs() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
        For Each codec As ImageCodecInfo In codecs
            If codec.MimeType = mimeType Then
                Return codec
            End If
        Next
    End Function
    
  
    Function Ettienne_Thumbnail(ByVal Source_Img As System.Drawing.Image, ByVal height As Integer, ByVal width As Integer) As System.Drawing.Image
        Dim Dest_Img As System.Drawing.Image
        
        Dim inp As New IntPtr()
        Dim Orginal_Width As Integer
        Dim Orginal_Height As Integer
        Dim Aspect_ratio As Integer
        Orginal_Width = Source_Img.Width
        Orginal_Height = Source_Img.Height
        Aspect_ratio = Orginal_Height / height
        width = Orginal_Width / Aspect_ratio
        
        Dim thumbnail As System.Drawing.Image = New Bitmap(width, height)
        Dim objGraphics As System.Drawing.Graphics
        objGraphics = System.Drawing.Graphics.FromImage(thumbnail)
        objGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic
        objGraphics.SmoothingMode = SmoothingMode.HighQuality
        objGraphics.PixelOffsetMode = PixelOffsetMode.HighQuality
        objGraphics.CompositingQuality = CompositingQuality.HighQuality
        If Request.QueryString("thumb") = "false" Then
            Return Source_Img
        Else
            objGraphics.DrawImage(Source_Img, 0, 0, width, height)
            Return thumbnail
            
        End If
    End Function

Posted 06 July 2006 09:31

17 Glenn Jones
@Ettienne Thank you for adding the VB example, I am sure others readers of this post will find it very useful.
Posted 06 July 2006 19:42

18 Sebastien Comeau
Thanks!!! This is very nice. But me I have a problem with mime type. I have a Web Services for the resize of an image. My function accept a Stream(the image) and I want to know how a can determine in my web service wich mime type use without pass the files extension. With the Stream dertemine wich mime type use for the resize of the image and make the resize and return the new image in stream. The only problem is I resize my image always with "image/jpeg", but if I can dertermine wich will use with the stream. Please if you know the answer or you want more information, contact me! Sebastien Comeau sebastien.comeau@gnb.ca
Posted 19 September 2006 18:53

19 Mark Sternig
The above code works great for the GIF resize issue in .NET. Much obliged for the code snippets! I am still left with one challenege however. I am running several ASP.NET sites in a shared hosting envronment under Medium Trust. As a result, the OctreeQuantizer code which utilizes pointers and is attributed as "unsafe" cannot be executed. Have you (or anyone else) run into a similar situation and if so, any solutions? Thank you! - Mark
Posted 04 October 2006 05:16

20 Richard
Thank you very much.
Posted 04 October 2006 12:36

21 R. Jones
Awesome code. I had it working in minutes and my gif's are magically delicous.
Posted 06 October 2006 00:49

22 Rolf
Hi there,

Im looking for a way to COMPARE jpgs. I have to fish out all the rows in a database that have the same image, but each has a different filename!

Thanks

Posted 13 October 2006 10:16

23 Manjit Singh Dahiya
Hi every body
i was looking for method to improve jpeg image quality after generating the thumnails. this code help me a lot
thanks a lot
Manjit Singh Dahiya

Posted 02 January 2007 07:48

24 mikeS
Thanks for the tutorial.

Unfortunately, I enabled all of the ideas above and the output is still not nearly as good as desktop applications for the resizing.

Anyone know how to get this "Lanczos3Filter" from this example from codeproject working?

http://www.codeproject.com/csharp/imgresizoutperfgdiplus.asp

It would make a huge difference in quality.

Posted 23 January 2007 12:29

25 renaldas
thanks a lot. good article
Posted 03 February 2007 23:25

26 renaldas
This is my static function for resizer. for some reason it is not giving me a good quality still. Can somebady see what I'm missing here:

The method suppose to take the original Drawing.Image object, resize it and return the resized Drawing.Image.


public static System.Drawing.Image ImageResizer(System.Drawing.Image origImage, int intNewWidth, int intNewHeight)
    {
        System.Drawing.Image thumbnail = new System.Drawing.Bitmap(intNewWidth, intNewHeight);
        System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(thumbnail);

        System.Drawing.Imaging.ImageCodecInfo[] Info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
        System.Drawing.Imaging.EncoderParameters Params = new System.Drawing.Imaging.EncoderParameters(1);
        Params.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
       (System.Web.HttpContext.Current.Response.OutputStream, Info[1], Params);


        //set quality properties
        graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;


        graphic.DrawImage(origImage, 0, 0, intNewWidth, intNewHeight);
                
        return thumbnail;
    }


Posted 19 March 2007 18:37

27 Renaldas
In my previous post need to remove the following line of code: "(System.Web.HttpContext.Current.Response.OutputStream, Info[1], Params);"
Posted 20 March 2007 11:51

28 Fouad Romieh
Hi all why when i save the image to my hard it looses a little bit resolution whilst it still have a better resolution with output stream.
Posted 23 March 2007 09:42

29 Ravindranath
i wrote this following code in my cs file but it shows me "a generic GDI + error occured"

if (fileExt != ".jpeg")
 {
    System.Random strRandNum = new System.Random();
    strTemp = strRandNum.Next().ToString();
    ImageCodecInfo ici = null;
    ImageCodecInfo[] iCodecs = ImageCodecInfo.GetImageEncoders();
     foreach (ImageCodecInfo ic in iCodecs)
      {
        if (ic.MimeType == "image/jpeg")
         {
          ici = ic;
          break;
         }
      }
     EncoderParameters ep = new EncoderParameters(1);
     ep.Param[0] = new   EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)90);
  str = "E:/Images/" + strTemp;
  bmp.Save(str, ici, ep);
 
please tell me where the error is as soon as possible. Thank you
Posted 10 May 2007 12:41

30 Kris
Thnx for useful article! In our project we use next code: System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters(1); ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L); 75% of quality is enought...
Posted 05 June 2007 16:55

31 Brad
Awesome article. Helped me out so much. Thanks man.
Posted 28 June 2007 04:07

32 Car Fernand
this helped me out loads thanks for the great article!
Posted 25 September 2007 19:32

33 myyz
Good stuff. Really helped. Much better than the MS getThumbnail, which produces for me frequently GDI+ out of memory errors. For previous comments, people who work with images for a living in the .net arena have stated that the "out of memory" is a generic gdi error message meaning "something went wrong". Memory of any kind is not an issue, pool, special pool, physical or virtual memory.
Posted 26 September 2007 11:12

34 Andrew
Hi all,
Ettienne, I took your code and put it into a class library, here's what I ended up with if you or anyone else finds it useful:

Imports System.IO
Imports System.Drawing.Imaging
Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Class ImageResizer

   Public Sub ResizeToJPEG(ByVal ImagePath As String, ByVal OutputStream As Stream, Optional ByVal Quality As Integer = 100, Optional ByVal height As Integer = -1, Optional ByVal width As Integer = -1)

      Dim originalimg, thumb As System.Drawing.Image
      Try
         originalimg = Image.FromFile(ImagePath) ' Fetch User Filename

         If height = -1 Then height = originalimg.Height
         If width = -1 Then width = originalimg.Width

         thumb = MakeThumbnail(originalimg, height, width)

         Dim codecEncoder As ImageCodecInfo = GetEncoder("image/jpeg")
         Dim encodeParams As New EncoderParameters(1)
         Dim qualityParam As New EncoderParameter(Imaging.Encoder.Quality, Quality)
         encodeParams.Param(0) = qualityParam
         thumb.Save(OutputStream, codecEncoder, encodeParams)

         originalimg.Dispose()
         thumb.Dispose()
      Catch ex As Exception
         Throw New Exception("Error processing JPEG", ex)
      End Try
   End Sub

   Function GetEncoder(ByVal mimeType As String) As ImageCodecInfo
      Try
         Dim codecs() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
         For Each codec As ImageCodecInfo In codecs
            If codec.MimeType = mimeType Then
               Return codec
            End If
         Next
      Catch ex As Exception
         Throw New Exception("Error processing GetEncoder (MimeType)", ex)
      End Try
   End Function


   Function MakeThumbnail(ByVal Source_Img As System.Drawing.Image, ByVal height As Integer, ByVal width As Integer) As System.Drawing.Image
      Try
         Dim intOrginalWidth As Integer
         Dim intOrginalHeight As Integer
         Dim sngAspectRatio As Single

         intOrginalWidth = Source_Img.Width
         intOrginalHeight = Source_Img.Height
         sngAspectRatio = intOrginalHeight / height
         width = intOrginalWidth / sngAspectRatio

         Dim thumb As System.Drawing.Image = New Bitmap(width, height)
         Dim objGraphics As System.Drawing.Graphics
         objGraphics = System.Drawing.Graphics.FromImage(thumb)
         objGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic
         objGraphics.SmoothingMode = SmoothingMode.HighQuality
         objGraphics.PixelOffsetMode = PixelOffsetMode.HighQuality
         objGraphics.CompositingQuality = CompositingQuality.HighQuality

         objGraphics.DrawImage(Source_Img, 0, 0, width, height)
         Return thumb
      Catch ex As Exception
         Throw (New Exception("Error in MakeThumbnail", ex))
      End Try

   End Function

End Class



Then here is some sample code that resizes a directory of images and puts the results into dynamically created image controls.  "plhResize" is a placeholder control that determines where the images will appear...

      Try
         Dim myDirOriginals As New IO.DirectoryInfo("C:\SampleImages\Originals")
         Dim MyImage As New Image
         For Each File As System.IO.FileInfo In myDirOriginals.GetFiles
            If File.Extension = ".jpg" Then
               MyImage = New Image
               MyImage.ImageUrl = "DynamicImage.aspx?OriginalImageURL=" & File.FullName & "&Width=" & txtWidth.Text & "&Quality=" & txtQuality.Text
               plhResize.Controls.Add(MyImage)
            End If
         Next
      Catch ex As Exception
         Response.Write(ex.ToString)
      End Try


Another example saves the resized images to another directory:

   Protected Sub lnkSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkSave.Click
      Try
         Dim myImageManager As New libDotNetCoppermine.ImageResizer
         Dim myDirOriginals As New IO.DirectoryInfo("C:\SampleImages\Originals")
         Dim myDirOutput As New IO.DirectoryInfo("C:\SampleImages\Thumbs")

         If Not myDirOutput.Exists Then myDirOutput.Create()


         Dim MyFile As IO.FileInfo

         Dim StartTime As Date = Now

         For Each File As System.IO.FileInfo In myDirOriginals.GetFiles
            If File.Extension = ".jpg" Then
               MyFile = New IO.FileInfo(myDirOutput.FullName & "\thumb_" & File.Name)
               MyFile.Delete()

               Dim OutputStream As System.IO.FileStream = MyFile.Create
               myImageManager.ResizeToJPEG(File.FullName, OutputStream, 100, txtWidth.Text)
               OutputStream.Close()
               OutputStream.Dispose()
            End If
         Next

         'Dim EndTime As Date = Now

         Response.Write("Execution Time :" & Date.Now.Subtract(StartTime).TotalSeconds.ToString)
      Catch ex As Exception
         Response.Write(ex.ToString)
      End Try
   End Sub

Posted 12 October 2007 17:22

35 Andrew
Hi again,

I made more changes to allow for forcing resize by height, width, or none. Also, it's pobably easier to just point you to the codeplex project where it's all being added. Here's a link to the source code list:

http://www.codeplex.com/DotNetCoppermine/SourceControl/ListDownloadableCommits.aspx

In the source browser, navigate to DotNetCoppermine / libDotNetCoppermine / libFileManagement.vb

Posted 12 October 2007 18:20

36 Raj
My below code doesn't work ?
Any clues why this fails. I am inputing jpg files.

Code
------
Dim original as System.Drawing.Image  = System.Drawing.Image.FromFile(Server.MapPath("/Files/Wallpapers/") & Filename)

DIM height As Integer= original.Height
DIM width As Integer= original.Width

height=(101/width) * height
width=(101/width) * width


Dim newpic as New System.Drawing.Bitmap(width,height)
Dim newpic2 as New System.Drawing.Bitmap(width,height)

Dim gr as System.Drawing.Graphics  = System.Drawing.Graphics.FromImage(newPic)

Dim gr2 as System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newPic2)


gr.DrawImage(original, 0, 0, width, height)
gr2.DrawImage(original, 0, 0, width,height)


newPic.Save(Server.MapPath("Assets/Content/Wallpapers/Preview/") & Filename, System.Drawing.Imaging.ImageFormat.Jpeg)
		newPic.Save(Server.MapPath("Assets/Content/Wallpapers/ThumbNail/") & Filename, System.Drawing.Imaging.ImageFormat.Jpeg)

gr.Dispose()
newPic.Dispose()
original.Dispose()


Posted 06 November 2007 13:31

37 Jeff
I modified the resizetojpg metod to accept an image URL and container width and height. The method calculates the new image width and height based on the original image and the container size. This way, any image can be resized to the container that it will be placed in. Seems to work.

   Public Sub ResizeImage(ByVal ImagePath As String, Optional ByVal Quality As Integer = 100, Optional ByVal ContainerHeight As Integer = -1, Optional ByVal ContainerWidth As Integer = -1)

        Dim originalimg, thumb As System.Drawing.Image
        Try
            Dim Height As Integer
            Dim Width As Integer
            Dim client As New WebClient
            Dim objStream As System.IO.Stream
            Dim Image As System.Drawing.Image
            objStream = client.OpenRead(ImagePath)
            ' Get the image stream
            originalimg = System.Drawing.Image.FromStream(objStream)

            If originalimg.Height <= ContainerHeight And originalimg.Width <= ContainerWidth Then
                ' image fits within container, use full image size
                Height = ContainerHeight
                Width = ContainerWidth
            ElseIf originalimg.Height > ContainerHeight And originalimg.Width > ContainerWidth Then
                ' image height and width are both greater than container
                If (originalimg.Height / ContainerHeight) > (originalimg.Width / ContainerWidth) Then
                    Height = ContainerHeight
                    Width = (ContainerHeight / originalimg.Height) * originalimg.Width
                Else
                    Width = ContainerWidth
                    Height = (ContainerWidth / originalimg.Width) * originalimg.Height
                End If
            ElseIf originalimg.Width > ContainerWidth Then
                ' image height > container height
                Width = ContainerWidth
                Height = (ContainerWidth / originalimg.Width) * ContainerHeight
            Else
                ' image width > container width
                Height = ContainerHeight
                Width = (ContainerHeight / originalimg.Height) * ContainerWidth
            End If


            thumb = MakeThumbnail(originalimg, Height, Width)

            Dim codecEncoder As ImageCodecInfo = GetEncoder("image/jpeg")
            Dim encodeParams As New EncoderParameters(1)
            Dim qualityParam As New EncoderParameter(Imaging.Encoder.Quality, Quality)
            encodeParams.Param(0) = qualityParam
            thumb.Save(Response.OutputStream, codecEncoder, encodeParams)

            originalimg.Dispose()
            thumb.Dispose()
        Catch ex As Exception
            Throw New Exception("Error processing JPEG", ex)
        End Try
    End Sub

Posted 08 November 2007 20:09

38 Jeff
Renaldas: You code never applies the encoding to the image, so it only resizes.

Glen: this is a fantastic resource - thank you.

Basically, My need was to take an image (small photo) from an upload form (any size/type), resize it, ENCODE it to jpeg, and insert it as a bytearray in to SQL Image/blob without ever saving it to disc.

Still sorting this out - still have to covert back to byte array from memory stream before insert... Just worried about memory and buffer and the save to memory stream part....

Posted 18 January 2008 22:11

39 Rob
Do you purposely make it hard to read the code. Why make is so difficult.
Posted 20 February 2008 19:08

40 doug
Could someone please explain how the 6 lines of code at the top of this article works? I understand the first 4 lines, but after that it is unclear.

Line 5:
graphic.DrawImage(image, 0, 0, newWidth, newHeight); What does this do? Change the image object or the graphic object?

line 6: thumbnail.Save(Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg); How does the original image data ever get to the output stream?

Does line 5 actually change the graphic object, which in turn changes the thumbnail object? That's the only way I can see this as working, but this seems unusual.

I've tried this code and it seems to be working, just wondering how.

Posted 06 May 2008 14:26

41 Gustavo Ortega
Hello-
What would be the workaround when the original image is kind of large (eg. 9MB)? I'm asking this since it will throw an Out of Memory exception here:
graphic.DrawImage(origImage, 0, 0, intNewWidth, intNewHeight);
Thanks,
GO.

Posted 11 June 2008 20:52

42 Egli
Thanks for the article its great... Good Job! :D
Posted 08 July 2008 08:17

43 Suttons
nice, see: weight loss, http://weightloss.siteburg.com
Posted 09 July 2008 12:08

44 Ray Akkanson
Awesome article. Helped me out so much. Thanks man
Posted 02 October 2008 19:05

45 Luck
that's very useful! Thanks!!!!
Posted 04 December 2008 14:10

46 Joseph Marinaccio
THANK YOU!!! I was pulling my hair out until I stumbled upon your posting, thank you for sharing your knowledge!

-Joseph Marinaccio Marinaccio Family Design

Posted 13 January 2009 05:33

47 Dinesh Bolkensteyn
Great post.

However it looks like that hardcoded info[1] , where 1 is the magical number for JPEG is not so robust.

There is nothing in: http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imagecodecinfo.getimageencoders.aspx that actually allows you to do this ;)

In the post http://blogs.msdn.com/robgruen/archive/2004/07/11/179789.aspx there is method called "GetEncoderInfo" which looks more appropriate.

Posted 05 March 2009 10:13

48 software developer
Quite inspiring,

This really helps, you can really notice the difference,

Keep up the good work, Anyway, thanks for the post

Posted 27 October 2009 15:46

49 Tomas Matejka
Thanks a lot for this article. I've implemented your code in my project a it saved my deathline. Thanks again
Posted 12 December 2009 11:58

50 sein
Have you noticed that the code generate brighter lines around the thumbnailed image? Example: http://i48.tinypic.com/2hmd4bt.jpg (original thumbnail) http://i48.tinypic.com/27xqnvo.jpg (bigger)
Posted 04 February 2010 17:10

51 Luke Brown
Really useful. This has helped me immensely. Good work.
Posted 09 February 2010 16:24

52 Senthil
Hi,

How to use dpx images in .net for Reading & converting

THanks and Regards,
Senthilkumar P

Posted 19 February 2010 10:54

Comment Guidelines

All comments are moderated. Please keep comments relevant. Abusive, inappropriate and anonymous posts may be edited and/or removed.

Contact Details




Captcha

Comment