System.Drawing 并不支持所有平台上的所有像素格式。一旦我collected 差异(请参阅不同平台上可能的像素格式的限制部分)。我认为 MacOS 使用与 Linux 版本相同的包。
由于Bitmap 编码器无论如何都无法保存保留Format16bppArgb1555 像素格式的图像,我建议您使用最接近的兼容格式(例如,Format32bppArgb 而不是Format16bppArgb1555)创建Bitmap 实例,如果您真的想将颜色转换为ARGB1555 颜色空间,您可以使用Quantize 方法和PredefinedColorsQuantizer.Argb1555,使用我链接的相同库进行比较。你可以从NuGet下载。
免责声明:我没有在 MacOS 上测试它,但它可以在 Linux (Ubuntu) 上运行。
我没有为每个颜色值设置一个字节,而是尝试在红色、绿色和蓝色之间分配 16 位。例如红色 5 位,绿色 5 位,蓝色 5 位。
编辑:我已经在开发下一个版本,它将允许在任何平台上使用带有任何PixelFormat 的托管位图数据。请参阅公开的BitmapDataFactory.CreateBitmapData 方法(尚未在公开版本中提供,但如果您查看Development 分支,您已经可以使用它了)。
更新:
我有图像字节(即只表示图像的字节,没有标题),我正在测试图像字节解码成的图像格式是否为每像素 16 位。
现在我明白为什么需要以 16 位原始格式设置像素了。就像在 Linux/MacOS 中一样,System.Drawing.Bitmap 对最简单的解决方案的支持有限,如果您如上所述创建托管位图数据。
注意:我发布了一个pre-release,它使BitmapDataFactory.CreateBitmapData 方法可用,而无需检查我的开发分支。现在您可以将任何PixelFormat 的原始字节转换为Bitmap,如下所示:
(当然,如果pfGuess 不是实际格式,结果可能会很混乱)
public Bitmap ToBitmap(byte[] rawData, PixelFormat pfGuess, Size size)
{
// the result bitmap will be ARGB32, which works on every platform
Bitmap result = new Bitmap(size.Width, size.Height);
// we create an accessor for the result so we can quickly copy the translated pixels
using var bitmapDataDst = result.GetWritableBitmapData();
// For the managed source any pixel format will work.
// Please note though that unlike System.Drawing.Bitmap images,
// managed bitmap data never has padding bytes at the end of each line.
// So if your rawData has padding (eg. when size has odd width and pf is 16bpp),
// then maybe the best if you include the padding in width.
// See https://docs.microsoft.com/en-us/windows/win32/medfound/image-stride for details
using var bitmapDataSrc = BitmapDataFactory.CreateBitmapData(size, pfGuess);
// Checking if rawData is long enough. RowSize is the width in bytes.
if (rawData.Length < bitmapDataSrc.RowSize * size.Height)
throw new ArgumentException("rawData is too short");
int currentByte = 0;
// iterating through rows
for (int y = 0; y < size.Height; y++)
{
var rowSrc = bitmapDataSrc[y]; // has the specified pixel format
var rowDst = bitmapDataDst[y]; // has ARGB32 pixel format
// writing raw pixels
for (int x = 0; x < bitmapDataSrc.RowSize; x++)
rowSrc.WriteRaw<byte>(x, rawData[currentByte++]);
// copying the pixels interpreted as pfGuess to result
for (int x = 0; x < size.Width; x++)
rowDst[x] = rowSrc[x];
}
// The result bitmap is now populated from the arbitrarily interpreted raw data.
// As it has ARGB32 format you can save it on any platform without any issues.
return result;
}