将RichTextBox数据保存到图像

时间:2015-08-29 10:59:47

标签: .net richtextbox

我尝试使用下面的代码将rtf文件转换为Jpg图像,但它返回的参数无效异常。

byte[] fileBytes = File.ReadAllBytes(filePath + extension);
MemoryStream ms = new MemoryStream(fileBytes);
Image img = Image.FromStream(ms, true, false);
img.Save(filePath + extension);

1 个答案:

答案 0 :(得分:0)

您要做的是从文本文件中复制字节并将其插入图像中 你应该做什么,是从文本/ RTF /任何文件中读取字节,然后转换为图像。

不幸的是,由于richtextbox不支持在内部执行此操作,因此有几种方法可以执行此操作。

方法1:覆盖RichTextBox
您可以覆盖经典的richtextbox,并执行以下操作:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Text;

public static class Graphics_DrawRtfText 
{
    private static RichTextBoxDrawer rtfDrawer;
    public static void DrawRtfText(this Graphics graphics, string rtf, RectangleF layoutArea,float xFactor) 
    {
        if (Graphics_DrawRtfText.rtfDrawer == null) 
        {
            Graphics_DrawRtfText.rtfDrawer = new RichTextBoxDrawer();
        }
        Graphics_DrawRtfText.rtfDrawer.Rtf = rtf;
        Graphics_DrawRtfText.rtfDrawer.Draw(graphics, layoutArea,xFactor);
    }

    private class RichTextBoxDrawer : RichTextBox 
    {
        //Code converted from code found here: http://support.microsoft.com/kb/812425/en-us

        //Convert the unit used by the .NET framework (1/100 inch) 
        //and the unit used by Win32 API calls (twips 1/1440 inch)
        private const double anInch = 14.4;

        public void LineSpace()
        {
            SafeNativeMethods.PARAFORMAT2 fmt = new SafeNativeMethods.PARAFORMAT2();
            fmt.cbSize = Marshal.SizeOf(fmt);
            fmt.dwMask |= SafeNativeMethods.PFM_LINESPACING | SafeNativeMethods.PFM_SPACEAFTER;

            fmt.dyLineSpacing = (int)(22 * this.SelectionFont.SizeInPoints); // in twips
            // specify exact line spacing
            fmt.bLineSpacingRule = Convert.ToByte(4);
            SafeNativeMethods.SendMessage(this.Handle, SafeNativeMethods.EM_SETPARAFORMAT, 0, ref fmt); // 0 - to all text. 1 - only to seleted
        }

        public void LineSpace(int _linespace)
        {
            SafeNativeMethods.PARAFORMAT2 fmt = new SafeNativeMethods.PARAFORMAT2();
            fmt.cbSize = Marshal.SizeOf(fmt);
            fmt.dwMask |= SafeNativeMethods.PFM_LINESPACING | SafeNativeMethods.PFM_SPACEAFTER;

            fmt.dyLineSpacing = _linespace; // in twips
            // specify exact line spacing
            fmt.bLineSpacingRule = Convert.ToByte(4);
            SafeNativeMethods.SendMessage(this.Handle, SafeNativeMethods.EM_SETPARAFORMAT, 0, ref fmt); // 0 - to all text. 1 - only to seleted
        }

        protected override CreateParams CreateParams 
        {
            get 
            {
                CreateParams createParams = base.CreateParams;
                if (SafeNativeMethods.LoadLibrary("msftedit.dll") != IntPtr.Zero) 
                {
                    createParams.ExStyle |= SafeNativeMethods.WS_EX_TRANSPARENT; // transparent
                    createParams.ClassName = "RICHEDIT50W";
                }
                return createParams;
            }
        }

        private void DPToHIMETRIC(Graphics graphics,ref SizeF size)
        {
            size.Width = (size.Width * 2540.0f) / graphics.DpiX;
            size.Height = (size.Height * 2540.0f) / graphics.DpiY;
        }

        public void Draw(Graphics graphics, RectangleF layoutArea, float xFactor) 
        {
            System.Diagnostics.Debug.WriteLine("LayoutArea " + layoutArea);

            SizeF metaSize = layoutArea.Size;
            DPToHIMETRIC(graphics, ref metaSize);

            System.Diagnostics.Debug.WriteLine("MetaSize " + metaSize);

            IntPtr hdc = graphics.GetHdc();

            //create a metafile, convert the size to himetrics
            Metafile metafile = new Metafile(hdc, new RectangleF(0,0,metaSize.Width,metaSize.Height));

            graphics.ReleaseHdc(hdc);

            Graphics g = Graphics.FromImage(metafile);
            IntPtr hDCEMF = g.GetHdc();

            //Calculate the area to render.
            SafeNativeMethods.RECT rectLayoutArea;
            rectLayoutArea.Left = 0;
            rectLayoutArea.Top = 0;
            rectLayoutArea.Right = (int)((1440 * metaSize.Width + 2540 / 2) / 2540);
            rectLayoutArea.Bottom = (int)((1440 * metaSize.Height + 2540 / 2) / 2540);

            System.Diagnostics.Debug.WriteLine(String.Format("RectLayoutArea ({0},{1})",rectLayoutArea.Right,rectLayoutArea.Bottom));

            SafeNativeMethods.FORMATRANGE fmtRange;
            fmtRange.chrg.cpMax = -1;            //Indicate character from to character to 
            fmtRange.chrg.cpMin = 0;
            fmtRange.hdc = hDCEMF;                  //Use the same DC for measuring and rendering
            fmtRange.hdcTarget = hDCEMF;         //Point at printer hDC
            fmtRange.rc = rectLayoutArea;        //Indicate the area on page to print
            fmtRange.rcPage = rectLayoutArea;    //Indicate size of page

            IntPtr wParam = IntPtr.Zero;
            wParam = new IntPtr(1);

            //Get the pointer to the FORMATRANGE structure in memory
            IntPtr lParam = IntPtr.Zero;
            lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
            Marshal.StructureToPtr(fmtRange, lParam, false);

            SafeNativeMethods.SendMessage(this.Handle, SafeNativeMethods.EM_FORMATRANGE, wParam, lParam);
            SafeNativeMethods.SendMessage(this.Handle, SafeNativeMethods.EM_FORMATRANGE, wParam, IntPtr.Zero);

            //Free the block of memory allocated
            Marshal.FreeCoTaskMem(lParam);

            //Release the device context handle obtained by a previous call
            g.ReleaseHdc(hDCEMF);
            g.Dispose();

            hdc = graphics.GetHdc();
            int nHorzSize = SafeNativeMethods.GetDeviceCaps(hdc, SafeNativeMethods.DeviceCap.HORZSIZE);
            int nVertSize = SafeNativeMethods.GetDeviceCaps(hdc, SafeNativeMethods.DeviceCap.VERTSIZE);
            int nHorzRes = SafeNativeMethods.GetDeviceCaps(hdc, SafeNativeMethods.DeviceCap.HORZRES);
            int nVertRes = SafeNativeMethods.GetDeviceCaps(hdc, SafeNativeMethods.DeviceCap.VERTRES);
            int nLogPixelsX = SafeNativeMethods.GetDeviceCaps(hdc, SafeNativeMethods.DeviceCap.LOGPIXELSX);
            int nLogPixelsY = SafeNativeMethods.GetDeviceCaps(hdc, SafeNativeMethods.DeviceCap.LOGPIXELSY);
            graphics.ReleaseHdc(hdc);

            float fHorzSizeInches = nHorzSize / 25.4f;
            float fVertSizeInches = nVertSize / 25.4f;
            float fHorzFudgeFactor = (nHorzRes / fHorzSizeInches) / nLogPixelsX;
            float fVertFudgeFactor = (nVertRes / fVertSizeInches) / nLogPixelsY;

            System.Diagnostics.Debug.WriteLine("Fudge Factor " + fHorzFudgeFactor.ToString() + " " + fVertFudgeFactor.ToString() + " XFactor " + xFactor.ToString());

            Pen RedPen = new Pen(Color.Red);
            graphics.DrawRectangle(RedPen, layoutArea.X * xFactor, layoutArea.Y * xFactor, layoutArea.Width * xFactor, layoutArea.Height * xFactor);

            float Left = layoutArea.Left;
            float Top = layoutArea.Top;
            //layoutArea.X = layoutArea.Y = 0;
            layoutArea.Offset(-Left, -Top);
            layoutArea.Offset(Left / fHorzFudgeFactor, Top / fVertFudgeFactor);

            System.Drawing.Drawing2D.GraphicsState state = graphics.Save();
            graphics.ScaleTransform(fHorzFudgeFactor * xFactor, fVertFudgeFactor * xFactor);
            graphics.DrawImage(metafile, layoutArea);
            graphics.Restore(state);


            System.Diagnostics.Debug.WriteLine("Layout Aread : "+layoutArea);
       }

        #region SafeNativeMethods
        private static class SafeNativeMethods 
        {
            [DllImport("USER32.dll")]
            public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr LoadLibrary(string lpFileName);

            [DllImport("gdi32.dll")]
            public static extern int GetDeviceCaps(IntPtr hdc, DeviceCap nIndex);

            [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
            public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref PARAFORMAT2 lParam);

            [StructLayout(LayoutKind.Sequential)]
            public struct RECT 
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CHARRANGE 
            {
                public int cpMin;        //First character of range (0 for start of doc)
                public int cpMax;        //Last character of range (-1 for end of doc)
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct FORMATRANGE 
            {
                public IntPtr hdc;                //Actual DC to draw on
                public IntPtr hdcTarget;    //Target DC for determining text formatting
                public RECT rc;                        //Region of the DC to draw to (in twips)
                public RECT rcPage;                //Region of the whole DC (page size) (in twips)
                public CHARRANGE chrg;        //Range of text to draw (see earlier declaration)
            }

            public enum DeviceCap : int
            {
                /// <summary>
                /// Device driver version
                /// </summary>
                DRIVERVERSION = 0,
                /// <summary>
                /// Device classification
                /// </summary>
                TECHNOLOGY = 2,
                /// <summary>
                /// Horizontal size in millimeters
                /// </summary>
                HORZSIZE = 4,
                /// <summary>
                /// Vertical size in millimeters
                /// </summary>
                VERTSIZE = 6,
                /// <summary>
                /// Horizontal width in pixels
                /// </summary>
                HORZRES = 8,
                /// <summary>
                /// Vertical height in pixels
                /// </summary>
                VERTRES = 10,
                /// <summary>
                /// Number of bits per pixel
                /// </summary>
                BITSPIXEL = 12,
                /// <summary>
                /// Number of planes
                /// </summary>
                PLANES = 14,
                /// <summary>
                /// Number of brushes the device has
                /// </summary>
                NUMBRUSHES = 16,
                /// <summary>
                /// Number of pens the device has
                /// </summary>
                NUMPENS = 18,
                /// <summary>
                /// Number of markers the device has
                /// </summary>
                NUMMARKERS = 20,
                /// <summary>
                /// Number of fonts the device has
                /// </summary>
                NUMFONTS = 22,
                /// <summary>
                /// Number of colors the device supports
                /// </summary>
                NUMCOLORS = 24,
                /// <summary>
                /// Size required for device descriptor
                /// </summary>
                PDEVICESIZE = 26,
                /// <summary>
                /// Curve capabilities
                /// </summary>
                CURVECAPS = 28,
                /// <summary>
                /// Line capabilities
                /// </summary>
                LINECAPS = 30,
                /// <summary>
                /// Polygonal capabilities
                /// </summary>
                POLYGONALCAPS = 32,
                /// <summary>
                /// Text capabilities
                /// </summary>
                TEXTCAPS = 34,
                /// <summary>
                /// Clipping capabilities
                /// </summary>
                CLIPCAPS = 36,
                /// <summary>
                /// Bitblt capabilities
                /// </summary>
                RASTERCAPS = 38,
                /// <summary>
                /// Length of the X leg
                /// </summary>
                ASPECTX = 40,
                /// <summary>
                /// Length of the Y leg
                /// </summary>
                ASPECTY = 42,
                /// <summary>
                /// Length of the hypotenuse
                /// </summary>
                ASPECTXY = 44,
                /// <summary>
                /// Shading and Blending caps
                /// </summary>
                SHADEBLENDCAPS = 45,

                /// <summary>
                /// Logical pixels inch in X
                /// </summary>
                LOGPIXELSX = 88,
                /// <summary>
                /// Logical pixels inch in Y
                /// </summary>
                LOGPIXELSY = 90,

                /// <summary>
                /// Number of entries in physical palette
                /// </summary>
                SIZEPALETTE = 104,
                /// <summary>
                /// Number of reserved entries in palette
                /// </summary>
                NUMRESERVED = 106,
                /// <summary>
                /// Actual color resolution
                /// </summary>
                COLORRES = 108,

                // Printing related DeviceCaps. These replace the appropriate Escapes
                /// <summary>
                /// Physical Width in device units
                /// </summary>
                PHYSICALWIDTH = 110,
                /// <summary>
                /// Physical Height in device units
                /// </summary>
                PHYSICALHEIGHT = 111,
                /// <summary>
                /// Physical Printable Area x margin
                /// </summary>
                PHYSICALOFFSETX = 112,
                /// <summary>
                /// Physical Printable Area y margin
                /// </summary>
                PHYSICALOFFSETY = 113,
                /// <summary>
                /// Scaling factor x
                /// </summary>
                SCALINGFACTORX = 114,
                /// <summary>
                /// Scaling factor y
                /// </summary>
                SCALINGFACTORY = 115,

                /// <summary>
                /// Current vertical refresh rate of the display device (for displays only) in Hz
                /// </summary>
                VREFRESH = 116,
                /// <summary>
                /// Horizontal width of entire desktop in pixels
                /// </summary>
                DESKTOPVERTRES = 117,
                /// <summary>
                /// Vertical height of entire desktop in pixels
                /// </summary>
                DESKTOPHORZRES = 118,
                /// <summary>
                /// Preferred blt alignment
                /// </summary>
                BLTALIGNMENT = 119
            }

            public struct PARAFORMAT2
            {

                public int cbSize;

                public uint dwMask;

                public short wNumbering;

                public short wReserved;

                public int dxStartIndent;

                public int dxRightIndent;

                public int dxOffset;

                public short wAlignment;

                public short cTabCount;

                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]

                public int[] rgxTabs;

                // PARAFORMAT2 from here onwards.

                public int dySpaceBefore;

                public int dySpaceAfter;

                public int dyLineSpacing;

                public short sStyle;

                public byte bLineSpacingRule;

                public byte bOutlineLevel;

                public short wShadingWeight;

                public short wShadingStyle;

                public short wNumberingStart;

                public short wNumberingStyle;

                public short wNumberingTab;

                public short wBorderSpace;

                public short wBorderWidth;

                public short wBorders;

            }

            public const int EM_FORMATRANGE = WM_USER + 57;

            public const int PFM_SPACEAFTER = 128;

            public const int PFM_LINESPACING = 256;

            public const int EM_SETPARAFORMAT = 1095;

            public const int WM_USER = 0x0400;

            public const int WS_EX_TRANSPARENT = 0x20;

        }
        #endregion
    }
}

Read Answer Here

方法2:将控件中的纯文本转换为图像
这是一篇精彩的文章,可以帮助您自己实现整个事情:CodeProject Article