Declined
Last Updated: 16 Nov 2015 15:59 by ADMIN
ADMIN
Dess | Tech Support Engineer, Sr.
Created on: 16 Mar 2015 12:32
Category: RichTextEditor
Type: Bug Report
2
FIX. RadRichTextEditor - exported documents with RtfFormatProvider containing images are not loaded in WordPad
To reproduce:

1.Add some text to RadRichTextEditor.
2.Copy an image from a Word document and paste it to the RadRichTextEditor.
3.Export the document content with RtfFormatProvider.

When you try to open the exported .rtf file via WordPad, you will notice that the image is not loaded. Please refer to the attached files created by MS Word and RadRichTextEditor.
(Total attached files size should be smaller than 20mb. Allowed extensions: .zip, .rar, .jpg, .png, .gif)
2 comments
ADMIN
Stefan
Posted on: 16 Nov 2015 15:58
Hello Fabian,

we have reviewed this case thoroughly and here are our findings. Our provider follows the latest RTF format specifications by Microsoft (https://www.microsoft.com/en-us/download/confirmation.aspx?id=10725) and exports the images in Png format. 

Windows 7 comes with WordPad version 6.1. This version of WordPad seems incapable of showing Png images. We have tested the same file of ours on Windows 8.1, and the images are shown in WordPad. . The WordPad version under Windows 8.1 is 6.3, so this seems to be addressed there. 

However, as we wanted you to be able to show images in Windows 7 as well, we found a decoder that will convert the Png files to Wmf (as Wmf is displayed in WordPad 6.1). We hope that it will work for you.

Here is the decoder and a demo how to use it:

        private void radButton1_Click(object sender, EventArgs e)
        {
            using (Stream stream = File.Create("test.rtf"))
            {
                Telerik.WinForms.Documents.FormatProviders.Rtf.RtfFormatProvider provider = new Telerik.WinForms.Documents.FormatProviders.Rtf.RtfFormatProvider();
                provider.ExportSettings = new Telerik.WinForms.Documents.FormatProviders.Rtf.RtfExportSettings();
                provider.ExportSettings.ExportImagesInCompatibilityMode = true;
                provider.ExportSettings.ImageExporting += new EventHandler<Telerik.WinForms.Documents.FormatProviders.Rtf.ImageExportingEventArgs>(ExportSettings_ImageExporting);

                provider.Export(this.radRichTextEditor1.Document, stream);
            }
        }

        private void ExportSettings_ImageExporting(object sender, Telerik.WinForms.Documents.FormatProviders.Rtf.ImageExportingEventArgs e)
        {
            if (e.Extension == "png" && e.IsInCompatibilityGroup)
            {
                using (MemoryStream stream = new MemoryStream(e.ImageBytes))
                {
                    Bitmap bmp = new Bitmap(stream);
                    e.ImageBytes = WmfExporter.MakeMetafileStream(bmp).ToArray();
                    e.Extension = "wmf";
                }
            }
        }

        public class WmfExporter
        {
            [Flags]
            private enum EmfToWmfBitsFlags
            {
                EmfToWmfBitsFlagsDefault = 0x00000000,
                EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
                EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
                EmfToWmfBitsFlagsNoXORClip = 0x00000004
            }

            private static int MM_ISOTROPIC = 7;
            private static int MM_ANISOTROPIC = 8;

            [System.Runtime.InteropServices.DllImport("gdiplus.dll")]
            private static extern uint GdipEmfToWmfBits(IntPtr _hEmf, uint _bufferSize,
                byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            private static extern IntPtr SetMetaFileBitsEx(uint _bufferSize,
                byte[] _buffer);
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            private static extern IntPtr CopyMetaFile(IntPtr hWmf,
                string filename);
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            private static extern bool DeleteMetaFile(IntPtr hWmf);
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            private static extern bool DeleteEnhMetaFile(IntPtr hEmf);



            public static MemoryStream MakeMetafileStream(Bitmap image)
            {
                System.Drawing.Imaging.Metafile metafile = null;
                using (Graphics g = Graphics.FromImage(image))
                {
                    IntPtr hDC = g.GetHdc();
                    metafile = new System.Drawing.Imaging.Metafile(hDC, System.Drawing.Imaging.EmfType.EmfOnly);
                    g.ReleaseHdc(hDC);
                }

                using (Graphics g = Graphics.FromImage(metafile))
                {
                    g.DrawImage(image, 0, 0);
                }
                IntPtr _hEmf = metafile.GetHenhmetafile();
                uint _bufferSize = GdipEmfToWmfBits(_hEmf, 0, null, MM_ANISOTROPIC,
                    EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
                byte[] _buffer = new byte[_bufferSize];
                GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC,
                        EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
                IntPtr hmf = SetMetaFileBitsEx(_bufferSize, _buffer);
                string tempfile = Path.GetTempFileName();
                CopyMetaFile(hmf, tempfile);
                DeleteMetaFile(hmf);
                DeleteEnhMetaFile(_hEmf);

                var stream = new MemoryStream();
                byte[] data = File.ReadAllBytes(tempfile);
                //File.Delete (tempfile);
                int count = data.Length;
                stream.Write(data, 0, count);
                return stream;
            }
Fabian
Posted on: 06 Nov 2015 10:53
Hello Dess

This problem is still not solved. I need a fix or a workaround for this asap. Any idea how you can help me?

Thanks a lot
Fabian