Click to See Complete Forum and Search --> : JPG and EXIF, how to save without recompression?


Jpri
April 11th, 2003, 03:08 AM
I want to add or modify a image description of an EXIF image file (EXIF = JPEG plus additional information). After some research I am now able to read and write the image description with the PropertyItem data structure. These PropertyItems are very useful to avoid the bit manipulating in the diabolic file structure of an exif file. But the worse thing is: when writing the image with the changed or new description the picture part becomes recompressed. You can notice this at the file size, you add information to the file and the file size decreases. When you repeat changing the description, the image become more and more poor, because jpg is a lossy compression.
My question is: how do I load and save an jpg or exif file without recompressing the bitmap?

pareshgh
April 11th, 2003, 01:05 PM
you can check ImageFormat class where in they have sevral conversions,

for example,

Image im = Image.FromFile("someimage");


im.Save("somenewimage",ImageFormat.Exif);


Paresh

Jpri
April 14th, 2003, 06:41 AM
This is exactly what I have done, but it is not the right way to avoid a recompression. It seems to me that the save command doesn't remember the origin of the picture as a compressed file and applies a new compression while saving.

Jpri
April 22nd, 2003, 03:36 AM
Now I have found the solution. The trick is to rotate the picture at 90 degrees. In this case the framework supplies a lossless rewriting of a jpeg file. Here is the code for all interested in this:

private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for(j = 0; j < encoders.Length; ++j)
{
if(encoders[j].MimeType == mimeType)
return encoders[j];
} return null;
}

private void WriteNewDescriptionInImage(string Filename,string NewDescription)
{
Image Pic;
PropertyItem[] PropertyItems;
byte[] bDescription=new Byte[NewDescription.Length];
int i;
string FilenameTemp;
Encoder Enc=Encoder.Transformation;
EncoderParameters EncParms=new EncoderParameters(1);
EncoderParameter EncParm;
ImageCodecInfo CodecInfo=GetEncoderInfo("image/jpeg");

// copy description into byte array
for (i=0;i<NewDescription.Length;i++) bDescription[i]=(byte)NewDescription[i];

// load the image to change
Pic=Image.FromFile(Filename);

// put the new description into the right property item
PropertyItems=Pic.PropertyItems;
PropertyItems[0].Id=0x010e; // 0x010e as specified in EXIF standard
PropertyItems[0].Type=2;
PropertyItems[0].Len=NewDescription.Length;
PropertyItems[0].Value=bDescription;
Pic.SetPropertyItem(PropertyItems[0]);

// we cannot store in the same image, so use a temporary image instead
FilenameTemp=Filename+".temp";

// for lossless rewriting we must rotate the image for 90 degrees
EncParm=new EncoderParameter(Enc,(long)EncoderValue.TransformRotate90);
EncParms.Param[0]=EncParm;

// now write the rotated image with new description
Pic.Save(FilenameTemp,CodecInfo,EncParms);

// for computers with low memory and gigantic pictures: release memory now
Pic.Dispose();
Pic=null;
GC.Collect();

// delete the original file, will be replaced later
System.IO.File.Delete(Filename);

// we must rotate back the written picture
Pic=Image.FromFile(FilenameTemp);
EncParm=new EncoderParameter(Enc,(long)EncoderValue.TransformRotate270);
EncParms.Param[0]=EncParm;
Pic.Save(Filename,CodecInfo,EncParms);

// again release memory now
Pic.Dispose();
Pic=null;
GC.Collect();

// delete the temporary picture
System.IO.File.Delete(FilenameTemp);
}

pareshgh
April 22nd, 2003, 02:09 PM
GOOD. and thanks for your post for helping. :D

-Paresh