public static void DrawImage([NotNull] this ConsoleBuffer @this, [NotNull] ImageSource imageSource, int x, int y, int width, int height) { if (@this == null) { throw new ArgumentNullException(nameof(@this)); } var bmp = imageSource as BitmapSource ?? throw new ArgumentException("Only rendering of bitmap source is supported."); @this.OffsetX(ref x).OffsetY(ref y); int x1 = x, x2 = x + width, y1 = y, y2 = y + height; if ([email protected](ref x1, ref y1, ref x2, ref y2)) { return; } if (width != bmp.PixelWidth || height != bmp.PixelHeight) { bmp = new TransformedBitmap(bmp, new ScaleTransform((double)width / bmp.PixelWidth, (double)height / bmp.PixelHeight)); } if (bmp.Format != PixelFormats.Indexed4) { bmp = new FormatConvertedBitmap(bmp, PixelFormats.Indexed4, BitmapPalettes.Halftone8Transparent, 0.5); } const int bitsPerPixel = 4; int stride = 4 * (bmp.PixelWidth * bitsPerPixel + 31) / 32; byte[] bytes = new byte[stride * bmp.PixelHeight]; bmp.CopyPixels(bytes, stride, 0); Debug.Assert(bmp.Palette != null); for (int iy = y1, py = 0; iy < y2; iy++, py++) { ConsoleChar[] charsLine = @this.GetLine(iy); for (int ix = x1, px = 0; ix < x2; ix++, px++) { int byteIndex = stride * py + px / 2; int bitOffset = px % 2 == 0 ? 4 : 0; SetColor(ref charsLine[ix], bmp.Palette, (bytes[byteIndex] >> bitOffset) & 0b1111); } } }