WPF JpegEncoder / Decoder在磁盘读/写期间保留DPI精度

时间:2011-07-13 20:34:38

标签: wpf bitmap dpi

使用JpegEncoder / Decoder读取和写入BitmapSource到磁盘时遇到问题。以下代码示例说明了问题:

        //initialize with some dummy test data
        int outputHeight = 100;
        int outputWidth = 100;
        int outputStride = 100 * 3; //24 bpp            
        byte[] outputBytes = new byte[100 * outputStride];

        double dpiX = 20.5;
        double dpiY = 20.5;

        //generate image
        BitmapSource testOutput = BitmapImage.Create(outputWidth, outputHeight,
            dpiX, dpiY, PixelFormats.Bgr24, null,
            outputBytes, outputStride);

        Trace.Assert(testOutput.DpiX == dpiX); //succeeds
        Trace.Assert(testOutput.DpiY == dpiY); //succeeds

        //write to disk
        JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        using (FileStream fileStream = new FileStream(@"F:\Users\Caleb\Desktop\test.jpg", FileMode.Create))
        {
            encoder.Frames.Add(BitmapFrame.Create(testOutput));
            encoder.QualityLevel = 100;
            Trace.Assert(encoder.Frames[0].DpiX == dpiX); //succeeds
            Trace.Assert(encoder.Frames[0].DpiY == dpiY); //succeeds
            encoder.Save(fileStream);
        }

        //read back
        using (Stream imageStreamSource = new FileStream(@"F:\Users\Caleb\Desktop\test.jpg", FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource reread = decoder.Frames[0];

            Trace.Assert(reread.DpiX == dpiX); //fails; reread.DpiX is 21.0
            Trace.Assert(reread.DpiY == dpiY); //fails; reread.DpiY is 21.0
        }

如注释中所示,回读的DPI不等于输入值。似乎在编码或解码过程中,DPI属性被舍入到最近的像素。

有没有办法在从磁盘读回的图像的DPI属性中保留小数点右边的数字?

2 个答案:

答案 0 :(得分:0)

尽管API允许您传入double(因此传递的值类似于20.5),但DPI​​值是整数。因此,API将四舍五入(在您的情况下为最接近的整数)。你认为DPI为20.5和21.0之间有什么区别吗?

答案 1 :(得分:0)

好吧,不确定JpegBitmapEncoder / Decoder链上发生了什么,但是使用BmpBitmapEncoder / Decoder会产生精确到最接近10像素的结果。不理想,但它可能适用于我的应用程序。