/// <summary> /// Create a tmpfile which has the name like in the configured pattern. /// Used e.g. by the email export /// </summary> /// <param name="surface"></param> /// <param name="captureDetails"></param> /// <param name="outputSettings"></param> /// <returns>Path to image file</returns> public static string SaveNamedTmpFile(ISurface surface, ICaptureDetails captureDetails, SurfaceOutputSettings outputSettings) { string pattern = conf.OutputFileFilenamePattern; if (pattern == null || string.IsNullOrEmpty(pattern.Trim())) { pattern = "greenshot ${capturetime}"; } string filename = FilenameHelper.GetFilenameFromPattern(pattern, outputSettings.Format, captureDetails); // Prevent problems with "other characters", which causes a problem in e.g. Outlook 2007 or break our HTML filename = Regex.Replace(filename, @"[^\d\w\.]", "_"); // Remove multiple "_" filename = Regex.Replace(filename, @"_+", "_"); string tmpFile = Path.Combine(Path.GetTempPath(), filename); LOG.Debug("Creating TMP File: " + tmpFile); // Catching any exception to prevent that the user can't write in the directory. // This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218 try { ImageOutput.Save(surface, tmpFile, true, outputSettings, false); tmpFileCache.Add(tmpFile, tmpFile); } catch (Exception e) { // Show the problem MessageBox.Show(e.Message, "Error"); // when save failed we present a SaveWithDialog tmpFile = ImageOutput.SaveWithDialog(surface, captureDetails); } return(tmpFile); }
/// <summary> /// Create a byte[] from the image by saving it to a memory stream. /// Should be avoided if possible, as this uses a lot of memory. /// </summary> /// <returns>byte[]</returns> public byte[] ToByteArray() { using (MemoryStream stream = new MemoryStream()) { ImageOutput.SaveToStream(_surface, stream, _outputSettings); return(stream.ToArray()); } }
/// <summary> /// Save with showing a dialog /// </summary> /// <param name="surface"></param> /// <param name="captureDetails"></param> /// <returns>Path to filename</returns> public static string SaveWithDialog(ISurface surface, ICaptureDetails captureDetails) { string returnValue = null; using (SaveImageFileDialog saveImageFileDialog = new SaveImageFileDialog(captureDetails)) { DialogResult dialogResult = saveImageFileDialog.ShowDialog(); if (dialogResult.Equals(DialogResult.OK)) { try { string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension; SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(FormatForFilename(fileNameWithExtension)); if (conf.OutputFilePromptQuality) { QualityDialog qualityDialog = new QualityDialog(outputSettings); qualityDialog.ShowDialog(); } // TODO: For now we always overwrite, should be changed ImageOutput.Save(surface, fileNameWithExtension, true, outputSettings, conf.OutputFileCopyPathToClipboard); returnValue = fileNameWithExtension; IniConfig.Save(); } catch (System.Runtime.InteropServices.ExternalException) { MessageBox.Show(Language.GetFormattedString("error_nowriteaccess", saveImageFileDialog.FileName).Replace(@"\\", @"\"), Language.GetString("error")); } } } return(returnValue); }
/// <summary> /// Create a Base64String from the Surface by saving it to a memory stream and converting it. /// Should be avoided if possible, as this uses a lot of memory. /// </summary> /// <returns>string</returns> public string ToBase64String(Base64FormattingOptions formattingOptions) { using (MemoryStream stream = new MemoryStream()) { ImageOutput.SaveToStream(_surface, stream, _outputSettings); return(Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions)); } }
/// <summary> /// Create a byte[] from the image by saving it to a memory stream. /// Should be avoided if possible, as this uses a lot of memory. /// </summary> /// <returns>byte[]</returns> public byte[] ToByteArray() { using (MemoryStream stream = new MemoryStream()) { ImageOutput.SaveToStream(bitmap, null, stream, outputSettings); return(stream.ToArray()); } }
/// <summary> /// Create a Base64String from the image by saving it to a memory stream and converting it. /// Should be avoided if possible, as this uses a lot of memory. /// </summary> /// <returns>string</returns> public string ToBase64String(Base64FormattingOptions formattingOptions) { using (MemoryStream stream = new MemoryStream()) { ImageOutput.SaveToStream(bitmap, null, stream, outputSettings); return(System.Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions)); } }
/// <summary> /// Write Multipart Form Data directly to the HttpWebRequest response stream /// </summary> /// <param name="boundary">Multipart separator</param> /// <param name="name">Name of the thing</param> /// <param name="formDataStream">Stream to write to</param> public void WriteFormDataToStream(string boundary, string name, Stream formDataStream) { // Add just the first part of this param, since we will write the file data directly to the Stream string header = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{name}\"; filename=\"{Filename ?? name}\";\r\nContent-Type: {ContentType}\r\n\r\n"; formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header)); ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings); }
/// <summary> /// Write Multipart Form Data directly to the HttpWebRequest response stream /// </summary> /// <param name="boundary">Multipart separator</param> /// <param name="name">Name of the thing</param> /// <param name="formDataStream">Stream to write to</param> public void WriteFormDataToStream(string boundary, string name, Stream formDataStream) { // Add just the first part of this param, since we will write the file data directly to the Stream string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", boundary, name, fileName ?? name, "image/" + outputSettings.Format); formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header)); ImageOutput.SaveToStream(surface, formDataStream, outputSettings); }
/// <summary> /// Helper method to create a temp image file /// </summary> /// <param name="image"></param> /// <returns></returns> public static string SaveToTmpFile(ISurface surface, SurfaceOutputSettings outputSettings, string destinationPath) { string tmpFile = Path.GetRandomFileName() + "." + outputSettings.Format.ToString(); // Prevent problems with "other characters", which could cause problems tmpFile = Regex.Replace(tmpFile, @"[^\d\w\.]", ""); if (destinationPath == null) { destinationPath = Path.GetTempPath(); } string tmpPath = Path.Combine(destinationPath, tmpFile); LOG.Debug("Creating TMP File : " + tmpPath); try { ImageOutput.Save(surface, tmpPath, true, outputSettings, false); tmpFileCache.Add(tmpPath, tmpPath); } catch (Exception) { return(null); } return(tmpPath); }
public static void SetClipboardData(ISurface surface) { DataObject dataObject = new DataObject(); // This will work for Office and most other applications //ido.SetData(DataFormats.Bitmap, true, image); MemoryStream dibStream = null; MemoryStream dibV5Stream = null; MemoryStream pngStream = null; Image imageToSave = null; bool disposeImage = false; try { SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Create the image which is going to be saved so we don't create it multiple times disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave); try { // Create PNG stream if (config.ClipboardFormats.Contains(ClipboardFormat.PNG)) { pngStream = new MemoryStream(); // PNG works for e.g. Powerpoint SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings); pngStream.Seek(0, SeekOrigin.Begin); // Set the PNG stream dataObject.SetData(FORMAT_PNG, false, pngStream); } } catch (Exception pngEX) { LOG.Error("Error creating PNG for the Clipboard.", pngEX); } try { if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) { using (MemoryStream tmpBmpStream = new MemoryStream()) { // Save image as BMP SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false); ImageOutput.SaveToStream(imageToSave, null, tmpBmpStream, bmpOutputSettings); dibStream = new MemoryStream(); // Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14 dibStream.Write(tmpBmpStream.GetBuffer(), BITMAPFILEHEADER_LENGTH, (int)tmpBmpStream.Length - BITMAPFILEHEADER_LENGTH); } // Set the DIB to the clipboard DataObject dataObject.SetData(DataFormats.Dib, true, dibStream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // CF_DibV5 try { if (config.ClipboardFormats.Contains(ClipboardFormat.DIBV5)) { // Create the stream for the clipboard dibV5Stream = new MemoryStream(); // Create the BITMAPINFOHEADER BITMAPINFOHEADER header = new BITMAPINFOHEADER(imageToSave.Width, imageToSave.Height, 32); // Make sure we have BI_BITFIELDS, this seems to be normal for Format17? header.biCompression = BI_COMPRESSION.BI_BITFIELDS; // Create a byte[] to write byte[] headerBytes = BinaryStructHelper.ToByteArray <BITMAPINFOHEADER>(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 BitfieldColorMask colorMask = new BitfieldColorMask(); // Make sure the values are set colorMask.InitValues(); // Create the byte[] from the struct byte[] colorMaskBytes = BinaryStructHelper.ToByteArray <BitfieldColorMask>(colorMask); Array.Reverse(colorMaskBytes); // Write to the stream dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length); // Create the raw bytes for the pixels only byte[] bitmapBytes = BitmapToByteArray((Bitmap)imageToSave); // Write to the stream dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length); // Set the DIBv5 to the clipboard DataObject dataObject.SetData(FORMAT_17, true, dibV5Stream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // Set the HTML if (config.ClipboardFormats.Contains(ClipboardFormat.HTML)) { string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null); string html = getHTMLString(surface, tmpFile); dataObject.SetText(html, TextDataFormat.Html); } else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) { string html; using (MemoryStream tmpPNGStream = new MemoryStream()) { SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Do not allow to reduce the colors, some applications dislike 256 color images // reported with bug #3594681 pngOutputSettings.DisableReduceColors = true; // Check if we can use the previously used image if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed) { ImageOutput.SaveToStream(imageToSave, surface, tmpPNGStream, pngOutputSettings); } else { ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings); } html = getHTMLDataURLString(surface, tmpPNGStream); } dataObject.SetText(html, TextDataFormat.Html); } } finally { // we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone! // Check if Bitmap is wanted if (config.ClipboardFormats.Contains(ClipboardFormat.BITMAP)) { dataObject.SetImage(imageToSave); // Place the DataObject to the clipboard SetDataObject(dataObject, true); } else { // Place the DataObject to the clipboard SetDataObject(dataObject, true); } if (pngStream != null) { pngStream.Dispose(); pngStream = null; } if (dibStream != null) { dibStream.Dispose(); dibStream = null; } if (dibV5Stream != null) { dibV5Stream.Dispose(); dibV5Stream = null; } // cleanup if needed if (disposeImage && imageToSave != null) { imageToSave.Dispose(); } } }
/// <summary> /// A plain "write data to stream" /// </summary> /// <param name="dataStream"></param> public void WriteToStream(Stream dataStream) { // Write the file data directly to the Stream, rather than serializing it to a string. ImageOutput.SaveToStream(surface, dataStream, outputSettings); }
public static void SetClipboardData(ISurface surface) { DataObject dataObject = new DataObject(); // This will work for Office and most other applications //ido.SetData(DataFormats.Bitmap, true, image); MemoryStream dibStream = null; MemoryStream pngStream = null; Image imageToSave = null; bool disposeImage = false; try { SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Create the image which is going to be saved so we don't create it multiple times disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave); try { // Create PNG stream if (config.ClipboardWritePNG) { pngStream = new MemoryStream(); // PNG works for e.g. Powerpoint SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings); pngStream.Seek(0, SeekOrigin.Begin); // Set the PNG stream dataObject.SetData(FORMAT_PNG, false, pngStream); } } catch (Exception pngEX) { LOG.Error("Error creating PNG for the Clipboard.", pngEX); } try { if (config.ClipboardWriteDIB) { using (MemoryStream tmpBmpStream = new MemoryStream()) { // Save image as BMP SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false); ImageOutput.SaveToStream(imageToSave, null, tmpBmpStream, bmpOutputSettings); dibStream = new MemoryStream(); // Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14 dibStream.Write(tmpBmpStream.GetBuffer(), BITMAPFILEHEADER_LENGTH, (int)tmpBmpStream.Length - BITMAPFILEHEADER_LENGTH); } // Set the DIB to the clipboard DataObject dataObject.SetData(DataFormats.Dib, true, dibStream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // Set the HTML if (config.ClipboardWriteHTML) { if (config.ClipboardWriteHTMLDataUrl) { string html; using (MemoryStream tmpPNGStream = new MemoryStream()) { SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Do not allow to reduce the colors, some applications dislike 256 color images // reported with bug #3594681 pngOutputSettings.DisableReduceColors = true; // Check if we can use the previously used image if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed) { ImageOutput.SaveToStream(imageToSave, surface, tmpPNGStream, pngOutputSettings); } else { ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings); } html = getHTMLDataURLString(surface, tmpPNGStream); } dataObject.SetText(html, TextDataFormat.Html); } else { string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null); string html = getHTMLString(surface, tmpFile); dataObject.SetText(html, TextDataFormat.Html); } } } finally { // we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone! // Check if Bitmap is wanted if (config.ClipboardWriteBITMAP) { dataObject.SetImage(imageToSave); // Place the DataObject to the clipboard SetDataObject(dataObject, true); } else { // Place the DataObject to the clipboard SetDataObject(dataObject, true); } if (pngStream != null) { pngStream.Dispose(); pngStream = null; } if (dibStream != null) { dibStream.Dispose(); dibStream = null; } // cleanup if needed if (disposeImage && imageToSave != null) { imageToSave.Dispose(); } } }