I'm using following methods to load bitmap from jpeg file (JpegToBitmap):
private static Bitmap JpegToBitmap(string fileName)
{
FileStream jpg = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
JpegBitmapDecoder ldDecoder = new JpegBitmapDecoder(jpg, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapFrame lfFrame = ldDecoder.Frames[0];
Bitmap lbmpBitmap = new Bitmap(lfFrame.PixelWidth, lfFrame.PixelHeight);
Rectangle lrRect = new Rectangle(0, 0, lbmpBitmap.Width, lbmpBitmap.Height);
BitmapData lbdData = lbmpBitmap.LockBits(lrRect, ImageLockMode.WriteOnly, (lfFrame.Format.BitsPerPixel == 24 ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb));
lfFrame.CopyPixels(System.Windows.Int32Rect.Empty, lbdData.Scan0, lbdData.Height * lbdData.Stride, lbdData.Stride);
lbmpBitmap.UnlockBits(lbdData);
return lbmpBitmap;
}
And to save bitmap to jpeg file:
private static void SaveToJpeg(Bitmap bitmap, string filePath)
{
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
bitmap.Save(filePath, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
public static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
Bitmap pixels differs just a little bit, but this difference is significant for me:
Screenshot of values in matrix of colors of bitmap before save
Screenshot of values in same matrix of colors of bitmap after load
This matrixes are just 2-d arrays of Color got by standart bitmap.GetPixel(x,y) in a loop.
public ColorMatrix(Bitmap bitmap, int currHeight, int currWidth)
{
matrix = new Color[8, 8];
for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 8; x++)
{
matrix[y, x] = bitmap.GetPixel(x + currWidth, y + currHeight);
}
}
}
So, the question is: How can i load saved bitmap (in jpeg/png or whatever format) correctly?
There are three reasons:
JPEG encoding and decoding processes use floating point arithmetic on integer input.
The Cb and Cr components are often subsampled relative to the Y component during compression.
During the quantization (fancy word for integer division) phase, DCT coefficients are usually discarded.