/// <summary> /// Place the surface as Format17 bitmap on the clipboard /// </summary> /// <param name="clipboardAccessToken">IClipboardAccessToken</param> /// <param name="surface">ISurface</param> public static void SetAsFormat17(this IClipboardAccessToken clipboardAccessToken, ISurface surface) { // Create the stream for the clipboard using (var dibV5Stream = new MemoryStream()) { var outputSettings = new SurfaceOutputSettings(OutputFormats.bmp, 100, false); bool dispose = ImageOutput.CreateBitmapFromSurface(surface, outputSettings, out var bitmapToSave); // Create the BITMAPINFOHEADER var header = BitmapInfoHeader.Create(bitmapToSave.Width, bitmapToSave.Height, 32); // Make sure we have BI_BITFIELDS, this seems to be normal for Format17? header.Compression = BitmapCompressionMethods.BI_BITFIELDS; var headerBytes = BinaryStructHelper.ToByteArray(header); // Write the BITMAPINFOHEADER to the stream dibV5Stream.Write(headerBytes, 0, headerBytes.Length); // As we have specified BI_COMPRESSION.BI_BITFIELDS, the BitfieldColorMask needs to be added var colorMask = BitfieldColorMask.Create(); // Create the byte[] from the struct var colorMaskBytes = BinaryStructHelper.ToByteArray(colorMask); Array.Reverse(colorMaskBytes); // Write to the stream dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length); // Create the raw bytes for the pixels only var bitmapBytes = BitmapToByteArray(bitmapToSave); // Write to the stream dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length); // Reset the stream to the beginning so it can be written dibV5Stream.Seek(0, SeekOrigin.Begin); // Set the DIBv5 to the clipboard DataObject clipboardAccessToken.SetAsStream("Format17", dibV5Stream); if (dispose) { bitmapToSave.Dispose(); } } }