/// <summary> /// Returns an image from the clipboard and capture exception /// /// TODO: Deal with Image Transparency more reliably (DIB) /// https://stackoverflow.com/questions/30727343/fast-converting-bitmap-to-bitmapsource-wpf /// </summary> /// <returns>Bitmap captured or null</returns> public static Bitmap GetImage() { try { var dataObject = Clipboard.GetDataObject(); var formats = dataObject.GetFormats(true); if (formats == null || formats.Length == 0) { return(null); } var first = formats[0]; foreach (var f in formats) { Debug.WriteLine(" - " + f.ToString()); } if (formats.Contains("PNG")) { Debug.WriteLine("PNG"); using (MemoryStream ms = (MemoryStream)dataObject.GetData("PNG")) { ms.Position = 0; return((Bitmap) new Bitmap(ms)); } } // Guess at Chromium and Moz Web Browsers which can just use WPF's formatting else if (first == DataFormats.Bitmap || formats.Contains("text/_moz_htmlinfo")) { Debug.WriteLine("First == Bitmap"); BitmapSource src = null; for (int i = 0; i < 5; i++) { try { // This is notoriously unreliable so retry multiple time if it fails src = Clipboard.GetImage(); break; } catch { Thread.Sleep(10); // retry } } if (src == null) { return(null); } return(WindowUtilities.BitmapSourceToBitmap(src)); } else if (formats.Contains("System.Drawing.Bitmap")) // (first == DataFormats.Dib) { Debug.WriteLine("System.Drawing.Bitmap"); var bitmap = (Bitmap)dataObject.GetData("System.Drawing.Bitmap"); return(bitmap); } Debug.WriteLine("Fall through - WinForms"); return(System.Windows.Forms.Clipboard.GetImage() as Bitmap); } catch { return(null); } }
/// <summary> /// Handle pasting and handle images /// </summary> public void PasteOperation() { if (Clipboard.ContainsImage()) { string imagePath = null; var bmpSource = Clipboard.GetImage(); using (var bitMap = WindowUtilities.BitmapSourceToBitmap(bmpSource)) { imagePath = AddinManager.Current.RaiseOnSaveImage(bitMap); } if (!string.IsNullOrEmpty(imagePath)) { SetSelection($"![]({imagePath})"); PreviewMarkdownCallback(); // force a preview refresh return; } string initialFolder = null; if (!string.IsNullOrEmpty(MarkdownDocument.Filename) && MarkdownDocument.Filename != "untitled") { initialFolder = Path.GetDirectoryName(MarkdownDocument.Filename); } var sd = new SaveFileDialog { Filter = "Image files (*.png;*.jpg;*.gif;)|*.png;*.jpg;*.jpeg;*.gif|All Files (*.*)|*.*", FilterIndex = 1, Title = "Save Image from Clipboard as", InitialDirectory = initialFolder, CheckFileExists = false, OverwritePrompt = true, CheckPathExists = true, RestoreDirectory = true }; var result = sd.ShowDialog(); if (result != null && result.Value) { imagePath = sd.FileName; try { var ext = Path.GetExtension(imagePath)?.ToLower(); using (var fileStream = new FileStream(imagePath, FileMode.Create)) { BitmapEncoder encoder = null; if (ext == ".png") { encoder = new PngBitmapEncoder(); } else if (ext == ".jpg" || ext == ".jpeg") { encoder = new JpegBitmapEncoder(); } else if (ext == ".gif") { encoder = new GifBitmapEncoder(); } encoder.Frames.Add(BitmapFrame.Create(bmpSource)); encoder.Save(fileStream); } } catch (Exception ex) { MessageBox.Show("Couldn't copy file to new location: \r\n" + ex.Message, mmApp.ApplicationName); return; } string relPath = Path.GetDirectoryName(sd.FileName); if (initialFolder != null) { try { relPath = FileUtils.GetRelativePath(sd.FileName, initialFolder); } catch (Exception ex) { mmApp.Log($"Failed to get relative path.\r\nFile: {sd.FileName}, Path: {imagePath}", ex); } if (!relPath.StartsWith("..\\")) { imagePath = relPath; } } if (imagePath.Contains(":\\")) { imagePath = "file:///" + imagePath; } SetSelection($"![]({imagePath})"); PreviewMarkdownCallback(); // force a preview refresh } } else if (Clipboard.ContainsText()) { // just paste as is at cursor or selection SetSelection(Clipboard.GetText()); } }