我有一个函数,它将ushort数组转换为灰度图像。我进行转换,将值转换为字节数组,然后使用BitmapEncoder。
public static async Task<StorageFile> WriteableBitmapToStorageFile(ushort[,] image, bool isScaleValues, List<KeyValuePair<string, BitmapTypedValue>> metadata)
{
//Setup image
var imgHeight = image.GetLength(0);
var imgWidth = image.GetLength(1);
float maxVal = 1;
if (isScaleValues)
{
for (int i = 0; i < imgHeight; i++)
{
for (int j = 0; j < imgWidth; j++)
{
if (maxVal < image[i, j])
{
maxVal = image[i, j];
}
}
}
}
byte[] data = new byte[imgWidth * imgHeight];
if (image != null)
{
if (isScaleValues)
{
for (int x = 0; x < imgHeight; x++)
for (int y = 0; y < imgWidth; y++)
data[x * imgWidth + y] = (byte)(((double)UInt16.MaxValue * (double)image[x, y]) / (double)maxVal);
}
else
{
for (int x = 0; x < imgHeight; x++)
for (int y = 0; y < imgWidth; y++)
data[x * imgWidth + y] = (byte)image[x, y];
}
}
string FileName = "MyFile.png";
var file =
await
Windows.Storage.ApplicationData.Current.TemporaryFolder.CreateFileAsync(FileName,
CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Gray16, BitmapAlphaMode.Ignore,
(uint) imgWidth,
(uint) imgHeight,
2822.222222222222,
2822.222222222222,
data);
await encoder.BitmapProperties.SetPropertiesAsync(metadata);
await encoder.FlushAsync();
}
return file;
}我在SetPixelData得到了这个异常
“System.ArgumentException”类型的异常发生在mscorlib.ni.dll中,但未在用户代码中处理 WinRT信息: Windows.Graphics.Imaging:不支持位图像素格式。 附加信息:参数不正确。 Windows.Graphics.Imaging:不支持位图像素格式。
二维ushort阵列已经是16位灰度图像,第一维是高度,第二是宽度。由于灰度显然不受支持,我需要将其保存为Rgba16,所以问题是:如何将灰度转换为RBG?
AFAIK,我只需要将所有R,G,B设置为相同的值,但是如何将值放在数组中。
二进制的RGBA16格式是什么?
发布于 2016-09-23 06:43:48
因为你有一个二维的ushort数组包含16个bpp灰度像素。我建议您首先使用这个数组创建具有Gray16像素格式的,然后使用SoftwareBitmap.Convert方法将其转换为Rgba16像素格式。
BitmapPixelFormat.Gray16表示16个bpp灰度像素格式,这意味着每个像素需要两个字节。因此,我们需要一个字节数组,其长度是ushort数组的两倍,并使用BitConverter.GetBytes(UInt16)方法将ushort转换为byte[]。以下是一个简单的示例:
ushort[,] image = { { ushort.MinValue, ushort.MaxValue, ushort.MaxValue }, { ushort.MaxValue, ushort.MinValue, ushort.MaxValue }, { ushort.MaxValue, ushort.MaxValue, ushort.MinValue } };
var imgHeight = image.GetLength(0);
var imgWidth = image.GetLength(1);
byte[] data = new byte[image.Length * 2];
for (int i = 0; i < imgHeight; i++)
{
for (int j = 0; j < imgWidth; j++)
{
byte[] byteArray = BitConverter.GetBytes(image[i, j]);
data[i * imgWidth * 2 + j * 2] = byteArray[0];
data[i * imgWidth * 2 + j * 2 + 1] = byteArray[1];
}
}
//Create a SoftwareBitmap with 16 bpp grayscale pixel format
var softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Gray16, imgWidth, imgHeight);
softwareBitmap.CopyFromBuffer(data.AsBuffer());
//Convert pixel format to Rgba16 so that we can save it to the file
softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Rgba16);
var outputFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("MyFile.png", CreationCollisionOption.GenerateUniqueName);
//Save softwareBitmap to file
using (IRandomAccessStream stream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
// Create an encoder with the desired format
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
// Set the software bitmap
encoder.SetSoftwareBitmap(softwareBitmap);
await encoder.FlushAsync();
}https://stackoverflow.com/questions/39622621
复制相似问题