WPF JpegEncoder / Decoder сохраняет точность DPI во время чтения / записи на диск - PullRequest
0 голосов
/ 14 июля 2011

Я столкнулся с проблемой при чтении и записи BitmapSource на диск с использованием JpegEncoder / Decoder. Следующий пример кода иллюстрирует проблему:

        //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 голосов
/ 14 июля 2011

Ну, не уверен, что происходит с цепочкой JpegBitmapEncoder / Decoder, но использование BmpBitmapEncoder / Decoder вместо этого дает результаты, которые с точностью до десятой доли пикселя. Не идеально, но это, вероятно, будет работать для моего приложения.

0 голосов
/ 14 июля 2011

Несмотря на то, что API позволяет передавать значение типа double (и, следовательно, значение, например 20,5), значения DPI являются целыми числами.Поэтому API округляется (в вашем случае) до ближайшего целого числа.Ожидаете ли вы разницу между DPI 20,5 и 21,0?

...