插入图片到RichTextBox
关于插入图片到RichTextBox,在网上找了下资料,大概就两种方法:
①、把图片拷贝到系统剪贴板,再复制到RichTextBox中,最后剪切板内容清空。
②、把图片文件转换成RFT格式,显示到RichTextBox中。
方法一:
很好理解,代码也简单。但是问题在于会改变原来系统剪贴板中内容,所以并不是一个很好实现方式。当然我们可以先备份剪贴板的中的内容,完事后再还原剪贴板内容。尝试了一下,可以实现,代码如下:
public void AddImage(Image img) { var obj = Clipboard.GetDataObject(); Clipboard.SetDataObject(img); DataFormats.Format format = DataFormats.GetFormat(DataFormats.Bitmap); if (this.CanPaste(format)) this.Paste(); Clipboard.SetDataObject(obj); //this.Rtf = this.InsertImage(img); }
方法二:
需要了解RTF格式和图元文件,话说对于这两个东西完全不明白,尝试找RTF指南看看,貌似都是英文。LZ的英文水平太烂,暂时作罢。网上找到代码,贴在这里,得空再研究一下RTF格式和图元文件。
private enum EmfToWmfBitsFlags { EmfToWmfBitsFlagsDefault = 0x00000000, EmfToWmfBitsFlagsEmbedEmf = 0x00000001, EmfToWmfBitsFlagsIncludePlaceable = 0x00000002, EmfToWmfBitsFlagsNoXORClip = 0x00000004 } private const int MM_ANISOTROPIC = 8; private const int HMM_PER_INCH = 2540; private const int TWIPS_PER_INCH = 1440; private float xDpi; private float yDpi; private const string RTF_HEADER = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033"; private string RTF_IMAGE_POST = @"}"; /// <summary> /// /// </summary> /// <param name="_image"></param> /// <returns></returns> public string InsertImage(Image _image) { StringBuilder _rtf = new StringBuilder(); _rtf.Append(RTF_HEADER); _rtf.Append(GetImagePrefix(_image)); _rtf.Append(GetRtfImage(_image)); _rtf.Append(RTF_IMAGE_POST); return _rtf.ToString(); } /// <summary> /// 获取图片前缀 /// </summary> /// <param name="_image">图片示例</param> /// <returns></returns> private string GetImagePrefix(Image _image) { StringBuilder _rtf = new StringBuilder(); int picw = (int)Math.Round((_image.Width / xDpi) * HMM_PER_INCH); int pich = (int)Math.Round((_image.Height / yDpi) * HMM_PER_INCH); int picwgoal = (int)Math.Round((_image.Width / xDpi) * TWIPS_PER_INCH); int pichgoal = (int)Math.Round((_image.Height / yDpi) * TWIPS_PER_INCH); _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); /// <summary> /// 获取图片二进制格式 /// </summary> /// <param name="_image">图片示例</param> /// <returns></returns> private string GetRtfImage(Image _image) { StringBuilder _rtf = null; MemoryStream _stream = null; Graphics _graphics = null; Metafile _metaFile = null; IntPtr _hdc; try { _rtf = new StringBuilder(); _stream = new MemoryStream(); using (_graphics = this.CreateGraphics()) { _hdc = _graphics.GetHdc(); _metaFile = new Metafile(_stream, _hdc); _graphics.ReleaseHdc(_hdc); } using (_graphics = Graphics.FromImage(_metaFile)) { _graphics.DrawImage(_image, new Rectangle(0, 0, _image.Width, _image.Height)); } IntPtr _hEmf = _metaFile.GetHenhmetafile(); uint _bufferSize = GdipEmfToWmfBits(_hEmf, 0, null, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault); byte[] _buffer = new byte[_bufferSize]; uint _convertedSize = GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault); 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(); } } }