Blue Theme Orange Theme Green Theme Red Theme
 
Dundas Dashboard
Home | Forums | Videos | Photos | Downloads | Blogs | E-Books | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Login Close
User Id:
Password:
 
Forgot Password
Forgot Username
Why Register
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
 Resources  
Close
 Our Network  
Close
Search :       Advanced Search »
Home » GDI+ & Graphics » Making Thumbnails of Transparent Images in .NET and C#

Making Thumbnails of Transparent Images in .NET and C#

When I started writing web applications using .NET, I found myself in need to dynamically create thumbnails of images that could be uploaded by the user or pulled from a database.

Technologies: .NET 1.0/1.1, GDI+,Visual C# .NET
Total downloads : 825
Total page views :  65449
Rating :
 5/5
This article has been rated :  1 times
   Print Read/Post comments Post a comment  Rate  
   Email to a friend  Bookmark  Similar Articles  Author's other articles  
Download Files:
ThumbnailCode.zip
 
Become a Sponsor


Related EbooksTop Videos

When I started writing web applications using .NET, I found myself in need to dynamically create thumbnails of images that could be uploaded by the user or pulled from a database.

For 24 bits images, I quickly found the necessary code examples in the .NET framework documentation or on the web.

For 8 bits images, in particular transparent ones, this code did not work and I had to do more research.

The Drawing namespace provides us with several classes to work with images, in particular:

The Bitmap class that encapsulates a GDI+ bitmap, which consists of the pixel data for a graphics image and its attributes.

The Graphics class that encapsulates a GDI+ drawing surface.

The System.Drawing.Imaging namespace provides advanced GDI+ imaging functionality, in particular:

The BitmapData class specifies the attributes of a bitmap image and is used by the LockBits and UnlockBits methods of the Bitmap class.

The ImageFormat class specifies the format of the image.

The Encoder class encapsulates a globally unique identifier (GUID) that identifies the category of an image encoder parameter.

The ImageFormat class specifies the format of the image. (gif, jpg, png...)

The way GDI+ loads and manipulates images of different formats and color depth is not well documented, but the VS debugger helps to find what happens in different cases and it is not always what one would expect.

For example:

If you load an 8 bits transparent png image into a GDI+ Image object, it is converted to a 32 bits/pixel format, losing the palette and transparency.

If you load an 8 bits transparent gif image into a GDI+ Image object, it is kept as a 8 bits/pixel format, the palette and transparency are preserved.

If you load a 4 bits transparent gif image into a GDI+ Image object, it is converted to an 8 bits/pixel format, the 16 entries palette is preserved.

If you try to use the GetThumbnailImage method from the Image object to resize an 8 bits transparent gif image, the thumbnail you obtain is a 24 bits/pixel png file with loss of transparency.

So how do we create thumbnails of transparent images?

Original Gif Image

Png Thumbnail

First we have to start from a gif image, 4 or 8 bits/pixel since it will preserve the palette and transparency. (4 bits/pixel images will be converted to 8 bits/pixel)

Then we create a Bitmap object with the same properties that the original, but with the desired size for the thumbnail.

Then, since we have the same palette in both the original image and the thumbnail we just have to find for each pixel in the thumbnail, the color index scaled to the original image. A way to do this is though pointer arithmetic. It forces us to compile the code with the unsafe directive, but it has the advantage of a fast execution. The IndexedRezise method does that job:

void IndexedRezise(int xSize, int ySize)
{
BitmapData sourceData;
BitmapData targetData;
AdjustSizes(ref xSize, ref ySize);
scaledBitmap = new Bitmap(xSize, ySize, bitmap.PixelFormat);
scaledBitmap.Palette = bitmap.Palette;
sourceData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, bitmap.PixelFormat);
try
{
targetData = scaledBitmap.LockBits(new Rectangle(0, 0, xSize, ySize),
ImageLockMode.WriteOnly, scaledBitmap.PixelFormat);
try
{
xFactor = (Double) bitmap.Width / (Double) scaledBitmap.Width;
yFactor = (Double) bitmap.Height / (Double) scaledBitmap.Height;
sourceStride = sourceData.Stride;
sourceScan0 = sourceData.Scan0;
int targetStride = targetData.Stride;
System.IntPtr targetScan0 = targetData.Scan0;
unsafe
{
byte * p = (byte *)(void *)targetScan0;
int nOffset = targetStride - scaledBitmap.Width;
int nWidth = scaledBitmap.Width;
for(int y=0;y < scaledBitmap.Height;++y)
{
for(int x=0; x < nWidth; ++x )
{
p[0] = GetSourceByteAt(x, y);
++p;
}
p += nOffset;
}
}
}
finally
{
scaledBitmap.UnlockBits(targetData);
}
}
finally
{
bitmap.UnlockBits(sourceData);
}
}

First we need to get pointers to the color indexes of the thumbnail image and the original image. We get it though the Lockbits method of the Bitmap object. This method returns a BitmapData object which has a Scan0 property of type IntPtr, pointing to the beginning of the color indexes.

The BitmapData object also has a Stride property which represents the width of the image including some padding so that it is word aligned.

Then we go through each pixel of the thumbnail, making sure we skip the padding at the end of each line. (The padding is the Stride minus the actual width of the image)

For each pixel, we determine the color index of the original image using pointer arithmetic through the GetSourceByteAt method:

byte GetSourceByteAt(int x, int y)
{
unsafe
{
return ((byte*) ((int)sourceScan0 + (int)
(Math.Floor(y * yFactor) * sourceStride) + (int) Math.Floor(x * xFactor)))[0];
}
}

Our class adjusts the size of the thumbnail to keep it proportional to the original image if you pass 0 as one of the dimensions and allows to save the thumbnail as gif or png image format from a File or a Stream. (If I am right the dynamic creation of gif files on a server is not permitted according to the LCZ compression patent, so in that case, you would use the png format.)

It also allows the making thumbnails of jpg 24 bits images, using a bicubic transform with overload methods to vary the jpeg compression.

The little demo program included lets you test the class by measuring the time needed to create 100 thumbnails of each image format, showing that the resizing of an 8 bits/pixel gif is about 3 times faster than the same operation for a jpeg image of the same size.


Login to add your contents and source code to this article
 [Top] Rate this article
 About the author
 
Jacques Philip
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architecture with many properties&events. Optional automatic layout.
Dundas Software
Dundas Chart for .NET is the most advanced .NET charting package available today.  With an extremely complete feature set, elegant architecture and easy implementation, Dundas Chart can quickly add advanced Charting functionality to enhance and transform ASP.NET and Windows Forms applications.  Whether you are implementing charting into internal projects, or building applications for clients, Dundas Chart offers advanced technology and advanced results to get the most out of data.
Clickatell's SMS Gateway
Clickatell's Developer Solutions allow you to SMS enable any website or application via a range of API's. Learn More about our API connections.
Free access to .NET Memory Management video
Everything you need to know about Garbage Collection, Temporary Objects, Fragmentation, Finalization and common causes of memory leaks in .NET. Watch the video here.
Microsoft Visual Studio 2010
Microsoft Visual Studio 2010 offers more to developers than any other Visual Studio release. Work more productively and collaboratively-with greater control over your work at every step. The Beta 2 can give you a head start on achieving efficiency.
 
   Print Read/Post comments Post a comment  Rate  
   Email to a friend  Bookmark  Similar Articles  Author's other articles  
Download Files:
ThumbnailCode.zip
 
 Post a Feedback, Comment, or Question about this article
Subject:  
Comment:  
Dundas Dashboard
Become a Sponsor
 Comments
Maybe not so complicated? by Joshua On October 15, 2008

I recently tried this using just the .net objects and didn't find any trouble. The key was just to get the settings straight. Am I missing something here? See:

http://getlara.com/north-america/canada/alberta/edmonton/post/2008/10/13/png-jpg-gif-image-resize-with-net-with-transparency

 

Reply | Email | Delete | Modify | 
Provide VB Samples by Carmen On June 15, 2009
Hi Jacques,

The app works perfectly, but just in C#. Some piece of codes (i.e., unsafe {} block) that is supported by C# it's not supported in VB.Net. I tried to translate the code but without good results. I really appreciate the VB sample.

Thank you so much in advance.

Carmen
Reply | Email | Delete | Modify | 

 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Suggest an Idea  |  Media Kit
Current Version: 5.2009.6.2
 © 1999 - 2009  Mindcracker LLC. All Rights Reserved