【发布时间】:2017-04-03 16:16:53
【问题描述】:
我需要在我的通用 Windows 应用中显示 .pgm 图像。 XAML 图像控件不直接支持 .pgm 图像,因此我需要解决它。
网上有很多用c#打开.pgm文件的例子,但都是依赖于使用通用Windows平台不支持的Bitmap对象(System.Drawing和System.Windows.Media库不能使用)。
我有读取图像宽度和高度并读取字节数组中的像素的代码(包含表示灰色阴影的值 0-255)。
下一步是使用最终可以传递给 XAML Image.Source 的任何对象从 byte[] 数组中绘制图像(并在合理的时间内完成)。
我设法做的最好的事情是显示this 但实际图片应该看起来像this(由于某种原因,它显示图像 4x 并且颜色错误)。
我使用的代码:
public int width;
public int height;
public int maxVal; //255
public byte[] pixels;
public async Task<WriteableBitmap> ToWriteableBitmap()
{
WriteableBitmap writeableBitmap = new WriteableBitmap(width, height);
using (Stream stream = writeableBitmap.PixelBuffer.AsStream())
{
await stream.WriteAsync(pixels, 0, pixels.Length);
}
return writeableBitmap;
}
如果有关系,我还提供了用于将 .pgm 文件读取到 PgmImage 对象的代码,但我很确定这可以正常工作:
public static async Task<PgmImage> LoadFromFile(string file)
{
FileStream ifs = null;
await Task.Run( () =>
{
Task.Yield();
ifs = new FileStream(file, FileMode.Open, FileAccess.Read);
});
BinaryReader br = new BinaryReader(ifs);
string magic = NextNonCommentLine(br);
//if (magic != "P5")
// throw new Exception("Unknown magic number: " + magic);
string widthHeight = NextNonCommentLine(br);
string[] tokens = widthHeight.Split(' ');
int width = int.Parse(tokens[0]);
int height = int.Parse(tokens[1]);
string sMaxVal = NextNonCommentLine(br);
int maxVal = int.Parse(sMaxVal);
byte[] pixels = new byte[height * width];
for (int i = 0; i < height * width; i++)
{
pixels[i] = br.ReadByte();
}
return new PgmImage(width, height, maxVal, pixels);
}
static string NextAnyLine(BinaryReader br)
{
string s = "";
byte b = 0; // dummy
while (b != 10) // newline
{
b = br.ReadByte();
char c = (char)b;
s += c;
}
return s.Trim();
}
static string NextNonCommentLine(BinaryReader br)
{
string s = NextAnyLine(br);
while (s.StartsWith("#") || s == "")
s = NextAnyLine(br);
return s;
}
(这是一个稍微编辑过的版本:jamesmccaffrey.wordpress.com/2014/10/21/a-pgm-image-viewer-using-c)。 我应该提到,我更喜欢不依赖任何第三方库或 NuGet 包的解决方案,但我很绝望,因此对任何解决方案持开放态度。
【问题讨论】:
标签: c# xaml uwp bitmapimage pgm