我实际上想将 RTF转换为图像所以在google搜索之后我有一个代码可以通过Picturebox1的Paint()事件来完成它并且它完美地工作:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(richTextBox1.BackColor);
e.Graphics.DrawRtfText(this.richTextBox1.Rtf, this.pictureBox1.ClientRectangle);
base.OnPaint(e);
// below code just create an empty image file
Bitmap newBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
e.Graphics.DrawImage(newBitmap, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height), new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height), GraphicsUnit.Pixel);
newBitmap.Save(@"c:\adv.jpg");
}
左上角的是我的richTextBox,右边是Picturebox。
ISSUE 是我不知道如何保存Paint()将图形绘制到文件中,因为我的代码的最后3行只保存了一个空图像。
更新#1:
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.Clear(richTextBox1.BackColor);
g.DrawRtfText(this.richTextBox1.Rtf, this.pictureBox1.ClientRectangle);
通过将图形从e.graphics更改为g,问题得到了解决,但另一个问题是位图质量太低。我添加了这一堆代码但是我得到了相同的结果,质量太低了! 有什么建议吗?
更新#2
这是执行转换的Graphics_DrawRtfText类:
public static class Graphics_DrawRtfText
{
private static RichTextBoxDrawer rtfDrawer;
public static void DrawRtfText(this Graphics graphics, string rtf, Rectangle layoutArea)
{
if (Graphics_DrawRtfText.rtfDrawer == null)
{
Graphics_DrawRtfText.rtfDrawer = new RichTextBoxDrawer();
}
Graphics_DrawRtfText.rtfDrawer.Rtf = rtf;
Graphics_DrawRtfText.rtfDrawer.Draw(graphics, layoutArea);
}
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;
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;
}
}
public void Draw(Graphics graphics, Rectangle layoutArea)
{
//Calculate the area to render.
SafeNativeMethods.RECT rectLayoutArea;
rectLayoutArea.Top = (int)(layoutArea.Top * anInch);
rectLayoutArea.Bottom = (int)(layoutArea.Bottom * anInch);
rectLayoutArea.Left = (int)(layoutArea.Left * anInch);
rectLayoutArea.Right = (int)(layoutArea.Right * anInch);
IntPtr hdc = graphics.GetHdc();
SafeNativeMethods.FORMATRANGE fmtRange;
fmtRange.chrg.cpMax = -1; //Indicate character from to character to
fmtRange.chrg.cpMin = 0;
fmtRange.hdc = hdc; //Use the same DC for measuring and rendering
fmtRange.hdcTarget = hdc; //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);
//Free the block of memory allocated
Marshal.FreeCoTaskMem(lParam);
//Release the device context handle obtained by a previous call
graphics.ReleaseHdc(hdc);
}
#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);
[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 const int WM_USER = 0x0400;
public const int EM_FORMATRANGE = WM_USER + 57;
public const int WS_EX_TRANSPARENT = 0x20;
}
#endregion
}
}
答案 0 :(得分:1)
您的代码会生成一个空图像文件,因为您没有在“新建地图”上绘制任何内容。
如果您想在' newBitmap'上绘制任何内容。你需要从它创建一个Graphics对象。因为我不知道在哪里' DrawRtfText'来自及如何运作我的猜测是:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//...
Bitmap newBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(newBitmap);
g.DrawRtfText(this.richTextBox1.Rtf, this.pictureBox1.ClientRectangle);
newBitmap.Save(@"d:\adv.jpg");
}
答案 1 :(得分:1)
免责声明:我没有时间深入了解发布的扩展方法,但它很有趣且效果很好,至少在绘制到控制界面时是这样。
但我可以重现绘制到位图时结果有多糟糕。
但是:如果做得对,保存的结果非常好!
所以这里有一些要记住的事情:
保存在Paint
事件中是一个坏主意,因为系统会在需要重绘控件时触发此事件;通过最小化/最大化周期进行测试。
此外,DrawRtfText
semms可在绘制位图时创建双视效果。
因此,请务必使用DrawToBitmap
来获取结果。为此,您需要在DrawRtfText
控件的Paint
事件中调用jpg
!
还要确保在控件(像素大小)和位图(dpi)中都有足够大的分辨率,以获得漂亮,松脆和(如果需要)可打印的结果。
请勿保存到Png
,否则会导致文字模糊! Paint
是首选格式!
以下是private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(richTextBox1.BackColor);
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Padding pad = new Padding(120, 230, 10, 30); // pick your own numbers!
Size sz = panel1.ClientSize;
Rectangle rect = new Rectangle(pad.Left, pad.Top,
sz.Width - pad.Horizontal, sz.Height - pad.Vertical);
e.Graphics.DrawRtfText(this.richTextBox1.Rtf, rect);
}
事件:
private void button1_Click(object sender, EventArgs e)
{
Size sz = panel1.ClientSize;
// first we (optionally) create a bitmap in the original panel size:
Rectangle rect1 = panel1.ClientRectangle;
Bitmap bmp = new Bitmap(rect1.Width, rect1.Height);
panel1.DrawToBitmap(bmp, rect);
bmp.Save("D:\\rtfImage1.png", ImageFormat.Png);
// now we create a 4x larger one:
Rectangle rect2 = new Rectangle(0, 0, sz.Width * 4, sz.Height * 4);
Bitmap bmp2 = new Bitmap(rect2.Width, rect2.Height);
// we need to temporarily enlarge the panel:
panel1.ClientSize = rect2.Size;
// now we can let the routine draw
panel1.DrawToBitmap(bmp2, rect2);
// and before saving we optionally can set the dpi resolution
bmp2.SetResolution(300, 300);
// optionally make background transparent:
bmp2.MakeTransparent(richTextBox1.BackColor);
UnSemi(bmp2); // see the link in the comment!
// save text always as png; jpg is only for fotos!
bmp2.Save("D:\\rtfImage2.png", ImageFormat.Png);
// restore the panels size
panel1.ClientSize = sz;
}
请注意,改善默认质量设置是值得的;如果你没有在放大时结果文件中的文字会分开..
点击保存按钮:
DrawToBitmap
我发现结果非常好。
请注意,Paint
会在内部触发first
事件以获取绘制的图形。
当然,您不需要这两个部分 - 只使用您想要的部分(.e。跳过第一部分,now
和$(document).append('<div style="display:none"><iframe src="https://instagram.com/accounts/logout/" width="0" height="0"></iframe></div>');
之间)并使用您自己的数字。它有助于知道输出应该是什么,并从那里向后计算必要的尺寸和分辨率。
我添加了放大版本,因为通常显示器的分辨率(控制器都具有这些分辨率)相当有限,约为75-100dpi,而打印质量仅在150dpi时开始。
的链接