Я столкнулся с проблемой при чтении и записи 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 изображения, считываемого с диска?