DotNetNuke

How to preserve EXIF data when rotating/resizing JPEG images

March 1, 2005

author:

How to preserve EXIF data when rotating/resizing JPEG images

.Net allows you to do some amazing things with graphics using GDI+. Its handling of image meta data leaves something to be desired though. It’s like they started to do something, but then abandoned it mid-way. In working on the Speerio File Manager Pro (for ASP.Net and DotNetNuke) product’s imaging functions, after considerable research, I decided that Omar Shahine’s PhotoLibrary was the best fit. It has some excellent functions especially in the EXIF area.

After playing with it for a while, I was disappointed to find that it, like just about every other EXIF-handler Google can find, does not preserve EXIF data on resize and rotate operations. I saw some commercial .Net components did it, so I knew could be done. But hours of searching later, all I knew for certain is that GDI+ can read EXIF data, but cannot write it to a new image. Bummer!

Not being one to give up easily, I experimenting a bit, and am pleased to have come up with a solution. Here is my JPEG resizing code which preserves EXIF data:

public static void ResizeJpeg(string filePath, int width, int height)
{
try

{

System.Drawing.Image imgPhoto = System.Drawing.Image.FromFile(filePath);

int sourceWidth = imgPhoto.Width;

int sourceHeight = imgPhoto.Height;

if (height == -1)

height = (int) ((float) sourceHeight * ((float) width/ (float) sourceWidth));

if (width == -1)

width = (int) ((float) sourceWidth * ((float) height/ (float) sourceHeight));

int sourceX = 0;

int sourceY = 0;

int destX = 0;

int destY = 0;

float nPercent = 0;

float nPercentW = 0;

float nPercentH = 0;

nPercentW = ((float)width/(float)sourceWidth);

nPercentH = ((float)height/(float)sourceHeight);

//if we have to pad the height pad both the top and the bottom

//with the difference between the scaled height and the desired height

if(nPercentH < nPercentW)

{

nPercent = nPercentH;

destX = (int)((width – (sourceWidth * nPercent))/2);

}

else

{

nPercent = nPercentW;

destY = (int)((height – (sourceHeight * nPercent))/2);

}

int destWidth = (int)(sourceWidth * nPercent);

int destHeight = (int)(sourceHeight * nPercent);

Bitmap bmPhoto = new Bitmap(imgPhoto, width, height);

bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

Graphics grPhoto = Graphics.FromImage(bmPhoto);

grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

grPhoto.DrawImage(imgPhoto,

new Rectangle(destX,destY,destWidth,destHeight),

new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),

GraphicsUnit.Pixel);

grPhoto.Dispose();

try

{

foreach (PropertyItem propertyItem in imgPhoto.PropertyItems)

{

try

{

bmPhoto.SetPropertyItem(propertyItem);

}

catch{}

}

}

catch{}

System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.Quality;

System.Drawing.Imaging.EncoderParameters encParms = new EncoderParameters(1);

System.Drawing.Imaging.EncoderParameter encParm = new EncoderParameter(enc,100L);

encParms.Param[0] = encParm;

ImageCodecInfo[] codecInfo = ImageCodecInfo.GetImageEncoders();

ImageCodecInfo codecInfoJpeg = codecInfo[1];

bmPhoto.Save(filePath+“.tmp”,codecInfoJpeg, encParms);

bmPhoto.Dispose();

imgPhoto.Dispose();

FileInfo fileInfo = new FileInfo(filePath);

fileInfo.Delete();

fileInfo = new FileInfo(filePath+“.tmp”);

fileInfo.MoveTo(filePath);

}

catch{}

}

Founder NftyDreams; founder Decentology; co-founder DNN Software; educator; Open Source proponent; Microsoft MVP; tech geek; creative thinker; husband; dad. Personal blog: http://www.kalyani.com. Twitter: @techbubble
Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.