Skip to content

Instantly share code, notes, and snippets.

@alaasayed7
Last active December 20, 2017 19:12
Show Gist options
  • Save alaasayed7/df9d7d418c72a0475231620f8aa5b888 to your computer and use it in GitHub Desktop.
Save alaasayed7/df9d7d418c72a0475231620f8aa5b888 to your computer and use it in GitHub Desktop.
C# RichTextBox InsertImage
#region Insert Image
private struct RtfFontFamilyDef
{
public const string Unknown = @"\fnil";
public const string Roman = @"\froman";
public const string Swiss = @"\fswiss";
public const string Modern = @"\fmodern";
public const string Script = @"\fscript";
public const string Decor = @"\fdecor";
public const string Technical = @"\ftech";
public const string BiDirect = @"\fbidi";
}
private enum EmfToWmfBitsFlags
{
// Use the default conversion
EmfToWmfBitsFlagsDefault = 0x00000000,
// Embedded the source of the EMF metafiel within the resulting WMF
// metafile
EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
// Place a 22-byte header in the resulting WMF file. The header is
// required for the metafile to be considered placeable.
EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
// Don't simulate clipping by using the XOR operator.
EmfToWmfBitsFlagsNoXORClip = 0x00000004
};
public static void InsertImage(this RichTextBox thiss, System.Drawing.Image _image)
{
StringBuilder _rtf = new StringBuilder();
Graphics _graphics = thiss.CreateGraphics();
var xDpi = _graphics.DpiX;
var yDpi = _graphics.DpiY;
// Append the RTF header
_rtf.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}
\viewkind4\uc1\pard\f0\fs17");
// Create the image control string and append it to the RTF string
_rtf.Append(GetImagePrefix(_image , xDpi , yDpi));
// Create the Windows Metafile and append its bytes in HEX format
_rtf.Append(GetRtfImage(_image,thiss));
// Close the RTF image control string
_rtf.Append(@"}\par}");
thiss.Select(thiss.TextLength, 0);
thiss.SelectedRtf = _rtf.ToString();
}
private static string GetImagePrefix(System.Drawing.Image _image , float xDpi , float yDpi)
{
StringBuilder _rtf = new StringBuilder();
// Calculate the current width of the image in (0.01)mm
int picw = (int)Math.Round((_image.Width / xDpi) * 2540);
// Calculate the current height of the image in (0.01)mm
int pich = (int)Math.Round((_image.Height / yDpi) * 2540);
// Calculate the target width of the image in twips
int picwgoal = (int)Math.Round((_image.Width / xDpi) * 1440);
// Calculate the target height of the image in twips
int pichgoal = (int)Math.Round((_image.Height / yDpi) * 1440);
// Append values to RTF string
_rtf.Append(@"{\pict\wmetafile8");
_rtf.Append(@"\picw");
_rtf.Append(picw);
_rtf.Append(@"\pich");
_rtf.Append(pich);
_rtf.Append(@"\picwgoal");
_rtf.Append(picwgoal);
_rtf.Append(@"\pichgoal");
_rtf.Append(pichgoal);
_rtf.Append(" ");
return _rtf.ToString();
}
[DllImportAttribute("gdiplus.dll")]
private static extern uint GdipEmfToWmfBits(IntPtr _hEmf, uint _bufferSize,
byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
private static string GetRtfImage(System.Drawing.Image _image , RichTextBox thiss)
{
StringBuilder _rtf = null;
// Used to store the enhanced metafile
MemoryStream _stream = null;
// Used to create the metafile and draw the image
Graphics _graphics = null;
// The enhanced metafile
Metafile _metaFile = null;
// Handle to the device context used to create the metafile
IntPtr _hdc;
try
{
_rtf = new StringBuilder();
_stream = new MemoryStream();
// Get a graphics context from the RichTextBox
using (_graphics = thiss.CreateGraphics())
{
// Get the device context from the graphics context
_hdc = _graphics.GetHdc();
// Create a new Enhanced Metafile from the device context
_metaFile = new Metafile(_stream, _hdc);
// Release the device context
_graphics.ReleaseHdc(_hdc);
}
// Get a graphics context from the Enhanced Metafile
using (_graphics = Graphics.FromImage(_metaFile))
{
// Draw the image on the Enhanced Metafile
_graphics.DrawImage(_image, new System.Drawing.Rectangle(0, 0, _image.Width, _image.Height));
}
// Get the handle of the Enhanced Metafile
IntPtr _hEmf = _metaFile.GetHenhmetafile();
// A call to EmfToWmfBits with a null buffer return the size of the
// buffer need to store the WMF bits. Use this to get the buffer
// size.
uint _bufferSize = GdipEmfToWmfBits(_hEmf, 0, null, 8,
EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
// Create an array to hold the bits
byte[] _buffer = new byte[_bufferSize];
// A call to EmfToWmfBits with a valid buffer copies the bits into the
// buffer an returns the number of bits in the WMF.
uint _convertedSize = GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer, 8,
EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
// Append the bits to the RTF string
for (int i = 0; i < _buffer.Length; ++i)
{
_rtf.Append(String.Format("{0:X2}", _buffer[i]));
}
return _rtf.ToString();
}
finally
{
if (_graphics != null)
_graphics.Dispose();
if (_metaFile != null)
_metaFile.Dispose();
if (_stream != null)
_stream.Close();
}
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment