/// <summary> /// Converts an 4-bit grayscale array to a bitmap. /// </summary> /// <param name="width">Width of the image</param> /// <param name="height">Height of the image</param> /// <param name="frame">4-bit grayscale array</param> /// <param name="hue">Hue in which the bitmap will be created</param> /// <param name="saturation">Saturation in which the bitmap will be created</param> /// <param name="luminosity">Maximal luminosity in which the bitmap will be created</param> /// <returns>Bitmap</returns> private static BitmapSource ConvertFromGray4(int width, int height, Frame frame, double hue, double saturation, double luminosity) { var bmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null); var bufferSize = (Math.Abs(bmp.BackBufferStride) * height + 2); var frameBuffer = new byte[bufferSize]; var index = 0; bmp.Lock(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var pixelLum = frame.Get(y * width + x); var lum = luminosity * pixelLum / 15; byte red, green, blue; ColorUtil.HslToRgb(hue, saturation, lum, out red, out green, out blue); frameBuffer[index] = blue; frameBuffer[index + 1] = green; frameBuffer[index + 2] = red; index += 4; } } bmp.WritePixels(new Int32Rect(0, 0, width, height), frameBuffer, bmp.BackBufferStride, 0); bmp.Unlock(); bmp.Freeze(); return(bmp); }
/// <summary> /// Converts a bitmap to an RGB24 array. /// </summary> /// <param name="bmp">Source bitmap</param> /// <param name="buffer">Destination buffer. Will be filled with RGB values for each pixel between 0 and 255.</param> /// <param name="offset">Offset in destination array</param> /// <param name="lum">Multiply luminosity</param> public static void ConvertToRgb24(BitmapSource bmp, byte[] buffer, int offset = 0, double lum = 1) { var bytesPerPixel = (bmp.Format.BitsPerPixel + 7) / 8; var bytes = new byte[bytesPerPixel]; var rect = new Int32Rect(0, 0, 1, 1); var pos = offset; for (var y = 0; y < bmp.PixelHeight; y++) { for (var x = 0; x < bmp.PixelWidth; x++) { rect.X = x; rect.Y = y; bmp.CopyPixels(rect, bytes, bytesPerPixel, 0); if (Math.Abs(lum - 1) > 0.01) { double hue, saturation, luminosity; byte r, g, b; ColorUtil.RgbToHsl(bytes[2], bytes[1], bytes[0], out hue, out saturation, out luminosity); ColorUtil.HslToRgb(hue, saturation, luminosity * lum, out r, out g, out b); buffer[pos] = r; buffer[pos + 1] = g; buffer[pos + 2] = b; } else { buffer[pos] = bytes[2]; // r buffer[pos + 1] = bytes[1]; // g buffer[pos + 2] = bytes[0]; // b } pos += 3; } } }
/// <summary> /// Converts an 2-bit grayscale array to a bitmap. /// </summary> /// <param name="width">Width of the image</param> /// <param name="height">Height of the image</param> /// <param name="frame">2-bit grayscale array</param> /// <param name="hue">Hue in which the bitmap will be created</param> /// <param name="saturation">Saturation in which the bitmap will be created</param> /// <param name="luminosity">Maximal luminosity in which the bitmap will be created</param> /// <returns>Bitmap</returns> private static BitmapSource ConvertFromGray2(int width, int height, Frame frame, double hue, double saturation, double luminosity) { if (frame.Size > 0 && frame.Size != width * height) { throw new ArgumentException($"Must convert to {width}x{height} but frame buffer is {frame.Size} bytes"); } var bmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null); var bufferSize = (Math.Abs(bmp.BackBufferStride) * height + 2); var frameBuffer = new byte[bufferSize]; var index = 0; bmp.Lock(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { try { var pixelLum = frame.Get(y * width + x); // 0 - 3 var lum = luminosity * pixelLum / 3; byte red, green, blue; ColorUtil.HslToRgb(hue, saturation, lum, out red, out green, out blue); frameBuffer[index] = blue; frameBuffer[index + 1] = green; frameBuffer[index + 2] = red; index += 4; } catch (IndexOutOfRangeException e) { Logger.Error(e, $"Converting {width}x{height} with {frame.Size} bytes: Trying to get pixel at position {y * width + x}"); throw; } } } bmp.WritePixels(new Int32Rect(0, 0, width, height), frameBuffer, bmp.BackBufferStride, 0); bmp.Unlock(); bmp.Freeze(); return(bmp); }
/// <summary> /// Converts a bitmap to an RGB24 array. /// </summary> /// <param name="bmp">Source bitmap</param> /// <param name="buffer">Destination buffer. Will be filled with RGB values for each pixel between 0 and 255.</param> /// <param name="offset">Offset in destination array</param> /// <param name="lum">Multiply luminosity</param> public static void ConvertToRgb24(BitmapSource bmp, byte[] buffer, int offset = 0, double lum = 1) { var stride = bmp.PixelWidth * (bmp.Format.BitsPerPixel / 8); var bytes = new byte[bmp.PixelHeight * stride]; bmp.CopyPixels(bytes, stride, 0); if (Math.Abs(lum - 1) > 0.01) { for (var i = 0; i < bytes.Length; i += 3) { double hue, saturation, luminosity; byte r, g, b; ColorUtil.RgbToHsl(bytes[i + 2], bytes[i + 1], bytes[i], out hue, out saturation, out luminosity); ColorUtil.HslToRgb(hue, saturation, luminosity * lum, out r, out g, out b); buffer[i] = r; buffer[i + 1] = g; buffer[i + 2] = b; } } else { unsafe { fixed(byte *pBuffer = buffer, pBytes = bytes) { byte *pB = pBuffer, pEnd = pBytes + bytes.Length; for (var pByte = pBytes; pByte < pEnd; pByte += 4, pB += 3) { *(pB) = *(pByte + 2); *(pB + 1) = *(pByte + 1); *(pB + 2) = *(pByte); } } } } }