System.Drawing
does not support every pixel format on all platforms. Once I collected the differences (see the Restrictions of Possible Pixel Formats on Different Platforms part). I think MacOS uses the same package as the Linux version.
As Bitmap
encoders cannot save images preserving the Format16bppArgb1555
pixel format anyway I suggest you to create a Bitmap
instance using the closest compatible format (for example, Format32bppArgb
instead of Format16bppArgb1555
), and if you really want to transform the colors into the ARGB1555
color space, you can use the Quantize
method with PredefinedColorsQuantizer.Argb1555
using the same library I linked for the comparison. You can download it from NuGet.
Disclaimer: I dit not test it on MacOS but it works in Linux (Ubuntu).
Rather than setting a byte for each color value, I'm trying to distribute 16 bits between red, green, and blue. For example 5 bits for red, 5 bits for green, and 5 bits for blue.
Edit: I'm already working on the next version, which will allow using a managed bitmap data with any PixelFormat
on any platform. See the public BitmapDataFactory.CreateBitmapData method (not available in a public release yet but you can already play with it if you check out the Development
branch).
Update:
I have image bytes (i.e. bytes representing only an image, no header), and I'm testing to see if the format of the image the image bytes decode to is 16 bits per pixel.
Now I see why you need to set pixels in a 16-bit raw format. As in Linux/MacOS the System.Drawing.Bitmap
has a limited support the easiest solution if you create managed bitmap data as I mentioned above.
Note: I published a pre-release, which makes the BitmapDataFactory.CreateBitmapData
method available without checking out my development branch. And now you can turn your raw bytes of any PixelFormat
to a Bitmap
like this:
(of course, if pfGuess
is not the actual format the result can be messy)
public Bitmap ToBitmap(byte[] rawData, PixelFormat pfGuess, Size size)
{
Bitmap result = new Bitmap(size.Width, size.Height);
using var bitmapDataDst = result.GetWritableBitmapData();
using var bitmapDataSrc = BitmapDataFactory.CreateBitmapData(size, pfGuess);
if (rawData.Length < bitmapDataSrc.RowSize * size.Height)
throw new ArgumentException("rawData is too short");
int currentByte = 0;
for (int y = 0; y < size.Height; y++)
{
var rowSrc = bitmapDataSrc[y];
var rowDst = bitmapDataDst[y];
for (int x = 0; x < bitmapDataSrc.RowSize; x++)
rowSrc.WriteRaw<byte>(x, rawData[currentByte++]);
for (int x = 0; x < size.Width; x++)
rowDst[x] = rowSrc[x];
}
return result;
}