【问题标题】:Loaded bitmap differs from saved one in jpeg (c#)加载的位图与 jpeg 中保存的位图不同(c#)
【发布时间】:2017-12-21 20:58:49
【问题描述】:

我正在使用以下方法从 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 或任何格式)?

【问题讨论】:

  • Jpeg 是一种有损格式。您永远不会完全加载您保存的像素。如果需要,请使用 png。

标签: c# image bitmap jpeg


【解决方案1】:

有三个原因:

  1. JPEG 编码和解码过程对整数输入使用浮点运算。

  2. 在压缩过程中,Cb 和 Cr 分量通常相对于 Y 分量进行二次采样。

  3. 在量化(整数除法的花哨词)阶段,DCT 系数通常被丢弃。

【讨论】:

  • 换句话说... jpeg 是一种有损压缩格式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
相关资源
最近更新 更多