加载的位图与jpeg中保存的位图不同(c#)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加载的位图与jpeg中保存的位图不同(c#)相关的知识,希望对你有一定的参考价值。

我正在使用以下方法从jpeg文件(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;
    }

并将位图保存到jpeg文件:

 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;
    }

位图像素略有不同,但这种差异对我很重要:

Screenshot of values in matrix of colors of bitmap before save

Screenshot of values in same matrix of colors of bitmap after load

这个矩阵只是由标准位图得到的二维颜色数组.GetPixel(x,y)在一个循环中。

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);
            }
        }
    }

所以,问题是:如何正确加载保存的位图(以jpeg / png或其他格式)?

答案

原因有三:

  1. JPEG编码和解码过程对整数输入使用浮点算法。
  2. 在压缩期间,Cb和Cr组分通常相对于Y组分进行二次采样。
  3. 在量化期间(整数除法的奇特的词)阶段,通常丢弃DCT系数。

以上是关于加载的位图与jpeg中保存的位图不同(c#)的主要内容,如果未能解决你的问题,请参考以下文章

delphi处理jpeg问题

如何保存位图

c#将位图保存到文件,保存目录错误?

位图保存 jpeg 失败但 png 可以,因为 comments 属性

如何在 c# 中的 iTextSharp pdf 中将位图显示为 jpeg 格式

使用 libjpeg / C++ 从文件中提取 JPEG 编码位图 (BMP) 图像