Lossless rotation of jpegs

  • Thread starter Thread starter Brian Smith
  • Start date Start date
B

Brian Smith

As has been documented on several sites, the CLR Imaging library supports
(theoretically) using a lossless rotation algorithm for jpeg files. This is
also used as a trick to re-Save an image without causing re-compression.

This does not seem to work in 1.1 - on most images I try, the file size is
reduced, and the resultant contents are subtly changed. Has this been broken
in the 1.1 framework, or is there some other method?

brian

---------------------------------------
sample code:
public void Rotate90(string fileName)
{
string FileNameTemp;
using (Image Pic = Image.FromFile(fileName))
{
Encoder Enc = Encoder.Transformation;
EncoderParameters EncParms = new EncoderParameters(1);
EncoderParameter EncParm;
ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg");

// we cannot store in the same image, so use a temporary image instead
FileNameTemp = Path.GetDirectoryName(fileName) + "\\rotated " +
Path.GetFileName(fileName);
if (File.Exists(FileNameTemp))
File.Delete(FileNameTemp) ;

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

// now save the rotated image
Pic.Save(FileNameTemp,CodecInfo,EncParms);
}
// delete the original file
File.Delete(fileName);
// rename to original
File.Move(FileNameTemp, fileName);
}
 
I've just tested this code under 1.0 and the same problem exists. So is
lossless rotation a myth?
On average, I find the jpeg is reduced by around 8%.

brian

P.S. Missing code from sample:
private ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] encoders ;
encoders = ImageCodecInfo.GetImageEncoders() ;
for (int j = 0; j < encoders.Length; j++)
{
if (encoders[j].MimeType == mimeType)
return encoders[j] ;
}
return null ;
}
 
The lossless rotation is for display only. If you're going to save the
result it gets compressed again - that's why you're seeing the size
difference.

Jerry

Brian Smith said:
I've just tested this code under 1.0 and the same problem exists. So is
lossless rotation a myth?
On average, I find the jpeg is reduced by around 8%.

brian

P.S. Missing code from sample:
private ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] encoders ;
encoders = ImageCodecInfo.GetImageEncoders() ;
for (int j = 0; j < encoders.Length; j++)
{
if (encoders[j].MimeType == mimeType)
return encoders[j] ;
}
return null ;
}


Brian Smith said:
As has been documented on several sites, the CLR Imaging library supports
(theoretically) using a lossless rotation algorithm for jpeg files. This is
also used as a trick to re-Save an image without causing re-compression.

This does not seem to work in 1.1 - on most images I try, the file size is
reduced, and the resultant contents are subtly changed. Has this been broken
in the 1.1 framework, or is there some other method?

brian

---------------------------------------
sample code:
public void Rotate90(string fileName)
{
string FileNameTemp;
using (Image Pic = Image.FromFile(fileName))
{
Encoder Enc = Encoder.Transformation;
EncoderParameters EncParms = new EncoderParameters(1);
EncoderParameter EncParm;
ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg");

// we cannot store in the same image, so use a temporary image instead
FileNameTemp = Path.GetDirectoryName(fileName) + "\\rotated " +
Path.GetFileName(fileName);
if (File.Exists(FileNameTemp))
File.Delete(FileNameTemp) ;

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

// now save the rotated image
Pic.Save(FileNameTemp,CodecInfo,EncParms);
}
// delete the original file
File.Delete(fileName);
// rename to original
File.Move(FileNameTemp, fileName);
}
 
That's true, but a bit of a red-herring. The real problem is not the
rotation but the ability to re-save an image that has not been altered
without recompressing it. Several sources have suggested that by performing
a (needless) rotation the CLR allows a re-save without re-compression. But
it doesn't actually work.
Since other tools do manage this task correctly (with or without rotation),
I'm looking for a .net solution..

brian

Jerry III said:
The lossless rotation is for display only. If you're going to save the
result it gets compressed again - that's why you're seeing the size
difference.

Jerry

Brian Smith said:
I've just tested this code under 1.0 and the same problem exists. So is
lossless rotation a myth?
On average, I find the jpeg is reduced by around 8%.

brian

P.S. Missing code from sample:
private ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] encoders ;
encoders = ImageCodecInfo.GetImageEncoders() ;
for (int j = 0; j < encoders.Length; j++)
{
if (encoders[j].MimeType == mimeType)
return encoders[j] ;
}
return null ;
}


Brian Smith said:
As has been documented on several sites, the CLR Imaging library supports
(theoretically) using a lossless rotation algorithm for jpeg files.
This
is
also used as a trick to re-Save an image without causing re-compression.

This does not seem to work in 1.1 - on most images I try, the file
size
is
reduced, and the resultant contents are subtly changed. Has this been broken
in the 1.1 framework, or is there some other method?

brian

---------------------------------------
sample code:
public void Rotate90(string fileName)
{
string FileNameTemp;
using (Image Pic = Image.FromFile(fileName))
{
Encoder Enc = Encoder.Transformation;
EncoderParameters EncParms = new EncoderParameters(1);
EncoderParameter EncParm;
ImageCodecInfo CodecInfo = GetEncoderInfo("image/jpeg");

// we cannot store in the same image, so use a temporary image instead
FileNameTemp = Path.GetDirectoryName(fileName) + "\\rotated " +
Path.GetFileName(fileName);
if (File.Exists(FileNameTemp))
File.Delete(FileNameTemp) ;

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

// now save the rotated image
Pic.Save(FileNameTemp,CodecInfo,EncParms);
}
// delete the original file
File.Delete(fileName);
// rename to original
File.Move(FileNameTemp, fileName);
}
 
Back
Top