/// <summary> /// Get a DIB from the Clipboard /// </summary> /// <param name="clipboardAccessToken"></param> /// <returns>Bitmap or null</returns> public static Bitmap GetAsDeviceIndependendBitmap(this IClipboardAccessToken clipboardAccessToken) { var formats = clipboardAccessToken.AvailableFormats().ToList(); if (!formats.Contains(StandardClipboardFormats.Bitmap.AsString())) { return(null); } var format17Bytes = clipboardAccessToken.GetAsBytes(StandardClipboardFormats.Bitmap.AsString()); var infoHeader = BinaryStructHelper.FromByteArray <BitmapInfoHeader>(format17Bytes); if (infoHeader.IsDibV5) { Log.Warn().WriteLine("Getting DIBV5 (format 17) when requesting DIB"); return(null); } // Bitmap version older than 5 var fileHeaderSize = Marshal.SizeOf(typeof(BitmapFileHeader)); var fileHeader = BitmapFileHeader.Create(infoHeader); var fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader); using (var bitmapStream = new MemoryStream()) { bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize); bitmapStream.Write(format17Bytes, 0, format17Bytes.Length); bitmapStream.Seek(0, SeekOrigin.Begin); var image = BitmapHelper.FromStream(bitmapStream); if (image != null) { return(image); } } return(null); }
/// <summary> /// Helper method to try to get an image in the specified format from the dataObject /// the DIB reader should solve some issues /// It also supports Format17/DibV5, by using the following information: http://stackoverflow.com/a/14335591 /// </summary> /// <param name="format">string with the format</param> /// <param name="dataObject">IDataObject</param> /// <returns>Bitmap or null</returns> private static Bitmap GetBitmapForFormat(string format, IDataObject dataObject) { var clipboardObject = GetFromDataObject(dataObject, format); var imageStream = clipboardObject as MemoryStream; if (!IsValidStream(imageStream)) { // TODO: add "HTML Format" support here... return(clipboardObject as Bitmap); } if (CoreConfig.EnableSpecialDIBClipboardReader) { if (format == FORMAT_17 || format == DataFormats.Dib) { Log.Info().WriteLine("Found DIB stream, trying to process it."); try { if (imageStream != null) { var dibBuffer = new byte[imageStream.Length]; imageStream.Read(dibBuffer, 0, dibBuffer.Length); var infoHeader = BinaryStructHelper.FromByteArray <BitmapInfoHeader>(dibBuffer); if (!infoHeader.IsDibV5) { Log.Info().WriteLine("Using special DIB <v5 format reader with biCompression {0}", infoHeader.Compression); var fileHeaderSize = Marshal.SizeOf(typeof(BitmapFileHeader)); var fileHeader = BitmapFileHeader.Create(infoHeader); var fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader); using (var bitmapStream = new MemoryStream()) { bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize); bitmapStream.Write(dibBuffer, 0, dibBuffer.Length); bitmapStream.Seek(0, SeekOrigin.Begin); var image = BitmapHelper.FromStream(bitmapStream); if (image != null) { return(image); } } } else { Log.Info().WriteLine("Using special DIBV5 / Format17 format reader"); // CF_DIBV5 var gcHandle = IntPtr.Zero; try { var handle = GCHandle.Alloc(dibBuffer, GCHandleType.Pinned); gcHandle = GCHandle.ToIntPtr(handle); return (new Bitmap(infoHeader.Width, infoHeader.Height, -(int)(infoHeader.SizeImage / infoHeader.Height), infoHeader.BitCount == 32 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb, new IntPtr(handle.AddrOfPinnedObject().ToInt32() + infoHeader.OffsetToPixels + (infoHeader.Height - 1) * (int)(infoHeader.SizeImage / infoHeader.Height)) )); } catch (Exception ex) { Log.Error().WriteLine(ex, "Problem retrieving Format17 from clipboard."); } finally { if (gcHandle == IntPtr.Zero) { GCHandle.FromIntPtr(gcHandle).Free(); } } } } } catch (Exception dibEx) { Log.Error().WriteLine(dibEx, "Problem retrieving DIB from clipboard."); } } } else { Log.Info().WriteLine("Skipping special DIB format reader as it's disabled in the configuration."); } try { if (imageStream != null) { imageStream.Seek(0, SeekOrigin.Begin); var tmpImage = BitmapHelper.FromStream(imageStream); if (tmpImage != null) { Log.Info().WriteLine("Got image with clipboard format {0} from the clipboard.", format); return(tmpImage); } } } catch (Exception streamImageEx) { Log.Error().WriteLine(streamImageEx, $"Problem retrieving {format} from clipboard."); } return(null); }