I have a c# application that contains an image gallery where I display some pictures. This gallery have some features including left and right rotation. everything is perfect but when I choose a picture from gallery and press rotation button (regardless left or right rotation), size of the picture increase significantly. It should be mentioned that the picture's format is JPEG.
Size of picture before rotation : 278 kb
Size of picture after rotation : 780 kb
My code for rotation is like bellow :
public Image apply(Image img)
{
Image im = img;
if (rotate == 1) im.RotateFlip(RotateFlipType.Rotate90FlipNone);
if (rotate == 2) im.RotateFlip(RotateFlipType.Rotate180FlipNone);
if (rotate == 3) im.RotateFlip(RotateFlipType.Rotate270FlipNone);
//file size is increasing after RotateFlip method
if (brigh != DEFAULT_BRIGH ||
contr != DEFAULT_CONTR ||
gamma != DEFAULT_GAMMA)
{
using (Graphics g = Graphics.FromImage(im))
{
float b = _brigh;
float c = _contr;
ImageAttributes derp = new ImageAttributes();
derp.SetColorMatrix(new ColorMatrix(new float[][]{
new float[]{c, 0, 0, 0, 0},
new float[]{0, c, 0, 0, 0},
new float[]{0, 0, c, 0, 0},
new float[]{0, 0, 0, 1, 0},
new float[]{b, b, b, 0, 1}}));
derp.SetGamma(_gamma);
g.DrawImage(img, new Rectangle(Point.Empty, img.Size),
0, 0, img.Width, img.Height, GraphicsUnit.Pixel, derp);
}
}
return im;
}
What is the problem?
In your case applying RotateFlip
on im
is changing the ImageFormat
from Jpeg
to MemoryBmp
.
By Default when you save the image it is going to make use of the default ImageFormat
. This will be the format returned by im.RawFormat
if you check the GUID im.RawFormat.Guid
Before RotateFlip
{b96b3cae-0728-11d3-9d7b-0000f81ef32e}
which is same as ImageFormat.Jpeg.Guid
After RotateFlip
{b96b3caa-0728-11d3-9d7b-0000f81ef32e}
which is same as ImageFormat.MemoryBmp.Guid
At the time of saving the image pass the ImageFormat
as the second parameter which will ensure that it uses the correct format. If not mentioned it is going to be the one in im.RawFormat
So If you want to save as jpeg at the time of saving call
im.Save("filename.jpg", ImageFormat.Jpeg);
This time the file size should be less than the original size.
Also note ImageFormat
is in System.Drawing.Imaging
namespace
NOTE
To control the quality of the jpeg make use of the overloaded Save method as mentioned in this MSDN Link
EDIT Based On Comment
OK assuming you are using SQL Server you must be having a image
datatype column (it is recommended to use varbinary(max)
instead of image
as in future it is going to be obselete (Read MSDN Post)
Now to the steps
1) read the contents as a stream / byte[] array
2) convert this to Image
3) perform rotate operation on the Image
4) convert this Image back to stream / byte[] array
5) Update the database column with the new value