Click here to Skip to main content
Sign Up to vote bad
good
Hi,
 
I've searched the entire internet for two consecutive days, with little to no success on this issue:
 
To append images in the System.Windows.Forms.RichTextBox class without copying to clipboard or any other dirty tricks, I have stumbled upon the ExRichTextBox class by Khendys Gordon here on http://www.codeproject.com
 
This class can convert an Image type to the corresponding RTF string which is needed to display it in the RichTextBox.
 
The RTF's picture control MUST be .WMF data either in binary or hexadecimals (this is also what WordPad does when you insert an image). WordPad and the RichTextBox ignores every other control word (e.g. PNG, JPG etc.) for pictures in RTF. See page 148 in the RTF Specification
 
Now here is the problem: http://puu.sh/1XnKL.jpg (image was 19x25 so I zoomed a little bit)
 
- The left one is converted from PNG to WMF using ExRichTextBox
 
- The right one is directly added to WordPad (so WordPad did the conversion)
 
Now, in the ExRichTextBox class the conversion goes by the following:
 
1. Create EMF from the Bitmap/Image,
2. then convert to WMF by using unmanaged code functions (in GDI+ API)
3. finally convert the bytes to hexadecimals
 
Here is the code of the method which returns the WMF data when you pass an Image type. This method is in the ExRichTextBox class which inherits from System.Windows.Forms.RichTextBox:
 
[DllImportAttribute("gdiplus.dll")]
private static extern uint GdipEmfToWmfBits (IntPtr _hEmf, uint _bufferSize,
    byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
 

private string GetRtfImage(Image _image) {
 
    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 = this.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 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, MM_ANISOTROPIC,
            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,
            MM_ANISOTROPIC, 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();
    }
}
 
Question: WHY and WHERE does the image lose its quality?
Posted 5-Feb-13 0:52am


2 solutions

When you convert from EMF to WMF, you are converting from a 32bit file to 16bit file - What is WMF?[^].
As a result, loss in quality is unavoidable.
  Permalink  
Comments
QuantumHive - 5-Feb-13 13:35pm
If it is unavoidable, then how does Microsoft manage to do this in WordPad WITHOUT the quality loss? (As you can see clearly the difference in the image I provided)
Yes. I agree with you. It definitely does lose quality. Good luck solving your problem.
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Your Filters
Interested
Ignored
     
0 Christian Graus 514
1 Ron Beyer 296
2 OriginalGriff 248
3 samadhan_kshirsagar 229
4 Tadit Dash 213
0 Sergey Alexandrovich Kryukov 7,007
1 Prasad_Kulkarni 3,815
2 OriginalGriff 3,557
3 _Amy 3,372
4 CPallini 2,975


Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 5 Feb 2013
Copyright © CodeProject, 1999-2013
All Rights Reserved. Terms of Use
Layout: fixed | fluid