如题,我现在想要把其中的图片存出来。找过网上的一些例子,但都是c或者c++的,看不懂。恳求各位达人,能不能给我个思路。或者将richtextbox整个截成一张图也行。要能把滚动条下的内容全部截到一起,而不是只截取看得见的内容。先谢谢大家了

解决方案 »

  1.   

    通过PRINTDOCUMENT 参考
    http://blog.csdn.net/zgke/archive/2008/11/06/3236058.aspx
      

  2.   

    谢谢zgke 
    但是现在问题是。不能直接打印出来,要把这个内容,存成一张图片。
      

  3.   

    谢谢 ximi82878 
    我现在就是想要这张图,请问该如何做转换呢?
      

  4.   

    zgke大哥已经说的很清楚了,如果要寸图片可以参考下面,curBitmap就是你要寸的图片 private void button2_Click(object sender, EventArgs e)
            {
                SaveFileDialog myDlg = new SaveFileDialog();
                myDlg.Title = "另存为";
                myDlg.OverwritePrompt = true;
                myDlg.Filter = "BMP文件 (*.bmp) | *.bmp|" +
                    "Gif文件 (*.gif) | *.gif|" +
                    "JPEG文件 (*.jpg) | *.jpg|" +
                    "PNG文件 (*.png) | *.png";
                myDlg.ShowHelp = true;            if (myDlg.ShowDialog() == DialogResult.OK)
                {
                    string fileName = myDlg.FileName;
                    string strfileEx = fileName.Remove(0, fileName.Length - 3);
                    switch (strfileEx)
                    { 
                        case "bmp":
                            curBitmap.Save(fileName, ImageFormat.Bmp);
                            break;                    case "jpg":
                            curBitmap.Save(fileName, ImageFormat.Jpeg);
                            break;                    case "gif":
                            curBitmap.Save(fileName, ImageFormat.Gif);
                            break;                    case "tif":
                            curBitmap.Save(fileName, ImageFormat.Tiff);
                            break;                    case "png":
                            curBitmap.Save(fileName, ImageFormat.Png);
                            break;                    default:
                            break;
                    }
                }        }
      

  5.   


     private   void   button1_Click(object   sender,   EventArgs   e)   
                      {   
                              OpenFileDialog   openFileDialog1   =   new   OpenFileDialog();   
                              openFileDialog1.Filter   =   "图片文件|*.jpg|所有文件|*.*";   
                              if   (openFileDialog1.ShowDialog()   ==   DialogResult.OK)   
                              {   
                                      Clipboard.SetDataObject(Image.FromFile(openFileDialog1.FileName),   false);   
                                      richTextBox1.Paste();   
                              }         
                      }
      

  6.   

    http://dev.csdn.net/Develop/article/28/67359.shtm
      

  7.   

    to Harvey_He zgke大哥的代码我试了。在 IntPtr hdc = e.Graphics.GetHdc();
    这一句之后知道Hdc被release之前。是无法操作 e.Graphics对象的。所以还是存不到图。
    不知道你的代码里curBitmap是从哪里来的。谢谢你的回复。
      

  8.   


    richtextbox控件有一个成员方法,叫做:DrawToBitmap……然后你把导出来的图片存起来就好了……还有什么需要?
      

  9.   

    Bitmap curBitmap = new Bitmap(PageInfo.Image);实验下
      

  10.   


    为什么我的C#中richtextbox控件没有这么个成员呢?
      

  11.   

    因为你可能用的是WPF中的RICHTEXTBOX,
    我说的是winform下的richtextbox
    如果你是WPF下的RICHTEXTBOX的话,根本就不用处理,你去查看一下flowdocument就可以了。
      

  12.   

    先复制richtextbox里面的所有内容到剪贴板(复制前清空剪贴板),然后取剪贴板内容中的图片信息
      

  13.   

    to meheartfly 试过这种方法。但是2张图的就取不出来了。也可能是我方法不对,请赐教。
    谢谢。
      

  14.   

    object obj = Clipboard.GetImage();就是这么简单
      

  15.   

    to meheartfly 你可以试一下如果rtb里有两张图片,或者图文混合的时候,
    GetImage取出来的是null;
      

  16.   

    看来用richtextbox不好实现,换别的方式吧
      

  17.   

    public static Bitmap RtbToBitmap(RichTextBox rtb) {
          rtb.Update();  // Ensure RTB fully painted
          Bitmap bmp = new Bitmap(rtb.Width, rtb.Height);
          using (Graphics gr = Graphics.FromImage(bmp)) {
            gr.CopyFromScreen(rtb.PointToScreen(Point.Empty), Point.Empty, rtb.Size);
          }
          return bmp;
        }那就试试这个吧。这个看得懂吧……那个 gr 很好用。
      

  18.   

    不过这个需要你的RTB上面没有任何的东西,使用起来要求还是很严格的。
    有一个很perfect的方法,不过怕你看不懂,呵呵,没有,其实挺简单的,想要么?
      

  19.   

    to hikaliv  谢谢,
    但是还有问题,如果这个rtb的内容不止一页,就是由滚动条的时候,滚动条下边的内容就不能在图上显示。to Harvey_He 
    没找到PageInfo,我在打印的事件里吧graphic取到了转存后的图片是一片漆黑
    太晕了。
    肯定是我的方法不对。
      

  20.   

    // 与 Win32接口通信
    [DllImport("USER32.dll")]
    private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
    private const int WM_USER = 0x400;
    private const int EM_FORMATRANGE = WM_USER + 57;// 再是所需要的结构体的定义:
    [StructLayout(LayoutKind.Sequential)]
    private struct RECT {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
    }
    // 望文生义吧[StructLayout(LayoutKind.Sequential)]
    private struct CHARRANGE {
    public int cpMin;
    public int cpMax;
    }[StructLayout(LayoutKind.Sequential)]
    private struct FORMATRANGE {
    public IntPtr hdc;
    public IntPtr hdcTarget;
    public RECT rc;
    public RECT rcPage;
    public CHARRANGE chrg;
    }
    // 将RTB上的内容格式化后画出来public static Bitmap RtbToBitmap(RichTextBox rtb)
    {
      return RtbToBitmap(rtb,rtb.ClientRectangle.Width,rtb.ClientRectangle.Height);
    }public Bitmap RtbToBitmap(RichTextBox rtb, int width, int height)
    {
      Bitmap bmp = new Bitmap(width, height); 
      using (Graphics gr = Graphics.FromImage(bmp))
      {
        System.IntPtr hDC = gr.GetHdc(); // 屏幕做为画源
        FORMATRANGE fmtRange;
        RECT rect;
        int fromAPI;
        rect.Top = 0; rect.Left = 0;
        rect.Bottom = (int)(bmp.Height + (bmp.Height * (bmp.HorizontalResolution / 100)) * inch);
        rect.Right = (int)(bmp.Width + (bmp.Width * (bmp.VerticalResolution / 100)) * inch);
        fmtRange.chrg.cpMin = 0;
        fmtRange.chrg.cpMax = -1;
        fmtRange.hdc = hDC;
        fmtRange.hdcTarget = hDC;
        fmtRange.rc = rect;
        fmtRange.rcPage = rect;
        int wParam = 1;
        System.IntPtr lParam = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
        System.Runtime.InteropServices.Marshal.StructureToPtr(fmtRange, lParam, false);
        fromAPI = SendMessage(rtb.Handle, EM_FORMATRANGE, wParam, lParam);
        System.Runtime.InteropServices.Marshal.FreeCoTaskMem(lParam);
        fromAPI = SendMessage(rtb.Handle, EM_FORMATRANGE, wParam, new IntPtr(0));
        gr.ReleaseHdc(hDC);
      }  return bmp;
    }
      

  21.   


    好吧,那还有一个更好的方法。你会格式化“绘画”文本吗?对于纯文本的内容的话,那么你就把所有的文本都缓存起来,然后建一个适当大的图,用Graphic.DrawText去往上面画!至于该做多大的图,你可以自己设定画上去的文字的大小和行间距,这一切都是由你来调整。我做过一个打印程序,就是这么干的。你这不是绘图,是打印文本。或者说,如果你问大家,该如何把RTB中的内容“打印”出来的话……
      

  22.   

    to hikaliv  
    你上边发的那段代码
    inch这个变量没有,我用10替换了它。
    存出来还是黑色的。
    这个inch是什么呢?你说的画文本的方式是不行的。因为rtb理由可能是图文混排的内容。谢谢
      

  23.   

    private const double inch = 14.4; // 与象素的换算。
    10嘛……差点……图文混排可就难了。除非你记录下来所有图片的位置,以及与文本的相对位置,打印的时候,到什么地方,就打印什么内容,graphic类里面有对应的方法。打印就是这么的,别无它法。我认为你这个问题,就是RICHTEXT打印。
      

  24.   

    hikaliv 
    其实打印,网上就有源码。但是我要的是存成图片。
      

  25.   


    你可以打印成图片啊……将 Graphic的源设为你要保存的image就行了。
      

  26.   

    都是黑的是因为你原来richtextbox里面没有东西,因此消息发送时不会通知系统去绘制那里,所以是黑的,也就是没有绘色。
    在绘图之前加上:            for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        bmp.SetPixel(i, j, Color.White);
                    }
                }将整个图先画成白色,然后再绘制richtextbox的内容。不过这种做法,仍然只能绘制 控件内的可见内容,对于不可见内容的绘制,请使用我在32楼提的方法。首先你要记录排版,然后将文本和图片定位“打印”到图片上。
      

  27.   

    怎么用到  句柄了的  顶    private  void  button1_Click(object  sender,  EventArgs  e)  
                      {  
                              OpenFileDialog  openFileDialog1  =  new  OpenFileDialog();  
                              openFileDialog1.Filter  =  "图片文件|*.jpg|所有文件|*.*";  
                              if  (openFileDialog1.ShowDialog()  ==  DialogResult.OK)  
                              {  
                                      Clipboard.SetDataObject(Image.FromFile(openFileDialog1.FileName),  false);  
                                      richTextBox1.Paste();  
                              }        
                      }
      

  28.   

    用 picturebox吧! 我就用的这个 变通一下  干嘛非得吊死在一棵 歪脖树上pictureBox1.Image.Save(Filename);就搞定了!
      

  29.   

      void WmfToBmp(int width,int height,char *metafile)   {   //width为图片宽度,height为图片高度,*metafile为元文件名   static HMETAFILE hmf;   char num[4];   FILE *fh;   HDC hMemDC;   HBITMAP hbmp,hold;   BITMAPFILEHEADER hdr;   LPBITMAPINFOHEADER lpbmpih;   HGLOBAL hg;      BitmapCount++;   if(BitmapCount==3)   {   width=128;   height=132;   }   if(BitmapCount==1)   {   width=80;   height=50;   }   ToString10(BitmapCount,num);   //把字符串转换成数字的函数   lstrcpy(bmpFile,FilePath);   lstrcat(bmpFile,num);   lstrcpy(gifFile,bmpFile);   lstrcat(bmpFile,".bmp");   lstrcat(gifFile,".gif");   hmf=GetMetaFile(metafile);   hDisplayDC=CreateDC("DISPLAY",NULL,NULL,NULL);   hMemDC=CreateCompatibleDC(hDisplayDC);   hg=GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER));   lpbmpih=(LPBITMAPINFOHEADER)GlobalLock(hg);   lpbmpih->biSize=sizeof(BITMAPINFOHEADER);   lpbmpih->biWidth=width;   lpbmpih->biHeight=height;   lpbmpih->biPlanes=1;   lpbmpih->biBitCount=8;   lpbmpih->biCompression=0;   hbmp=CreateCompatibleBitmap(hDisplayDC,width,height);   GlobalUnlock(hg);   GlobalFree(hg);   hold=SelectObject(hMemDC,hbmp);   SetMapMode(hMemDC,MM_ANISOTROPIC);   SetWindowOrgEx(hMemDC,0,0,NULL);   SetViewportExtEx(hMemDC,width,height,NULL);   PlayMetaFile(hMemDC,hmf);   hbmp=SelectObject(hMemDC,hold);   if((fh=fopen(bmpFile,"w+b"))==NULL)   {   return;   }   hdr.bfType=0x4d42;   hdr.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+width*height;   hdr.bfReserved1=0;   hdr.bfReserved2=0;   hdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);   fwrite((LPSTR)&hdr,sizeof(BITMAPFILEHEADER),1,fh);   hg=GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD));   lpbmpih=(LPBITMAPINFOHEADER)GlobalLock(hg);   lpbmpih->biSize=sizeof(BITMAPINFOHEADER);   lpbmpih->biWidth=width;   lpbmpih->biHeight=height;   lpbmpih->biPlanes=1;   lpbmpih->biBitCount=8;   lpbmpih->biCompression=0;   lpbmpih->biSizeImage=width*height;   lpbmpih->biClrUsed=256;   lpbmpih->biClrImportant=0;   j=GetDIBits(hMemDC,hbmp,0,height,NULL,(BITMAPINFO*)lpbmpih,DIB_RGB_COLORS);   lpbmpih->biSize=sizeof(BITMAPINFOHEADER);   fwrite(lpbmpih,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD),1,fh);   GetDIBits(hMemDC,hbmp,0,height,(LPSTR)FileBuffer,(BITMAPINFO*)lpbmpih,DIB_RGB_COLS);   fwrite(FileBuffer,width*height,1,fh);   GlobalUnlock(hg);   GlobalFree(hg);   fclose(fh);   DeleteDC(hMemDC);   DeleteDC(hDisplayDC);   DeleteObject(hbmp);   DeleteObject(hold);   DeleteMetaFile(hmf);   }//end function WmfToBmp() 
      

  30.   

    第二个是图片的问题,这也是本文的重点。RTF中图片以两种方式存在:第一种方式是直接嵌入,以{\pict开始;第二种方式是作为OLE对象嵌入,这时以{\object开始。当RTF处理器能直接使用OLE时,RTF文件中提供了OLE的数据;否则,文件中直接提供图片的数据,以{\result开始。在使用中最常见的图片格式是内含DIB BITMAP的元文件(METAFILE),这种格式在SDK中没有说明,而且在RTF中是以压缩形式储存的,所以在转换时有一定困难。我们采取了一种比较新的方法:先把META FILE的数据读出来存成一个文件,然后用GetMetafile和PlayMetafile函数把文件中的图形打印在一个内存DC上,最后用抓图的方法把它存成BITMAP文件。以下是具体程序: 
      

  31.   

           public int Print(int charFrom, int charTo, PrintPageEventArgs e)
            {
                //Calculate the area to render and print
                RECT rectToPrint;
                rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);
                rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);
                rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);
                rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);            //Calculate the size of the page
                RECT rectPage;
                rectPage.Top = (int)(e.PageBounds.Top * anInch);
                rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);
                rectPage.Left = (int)(e.PageBounds.Left * anInch);
                rectPage.Right = (int)(e.PageBounds.Right * anInch);            IntPtr hdc = e.Graphics.GetHdc();            FORMATRANGE fmtRange;
                fmtRange.chrg.cpMax = charTo; //Indicate character from to character to 
                fmtRange.chrg.cpMin = charFrom;
                fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering
                fmtRange.hdcTarget = hdc;              //Point at printer hDC
                fmtRange.rc = rectToPrint;             //Indicate the area on page to print
                fmtRange.rcPage = rectPage;            //Indicate size of page            IntPtr res = IntPtr.Zero;            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);            //Send the rendered data for printing 
                res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);            //Free the block of memory allocated
                Marshal.FreeCoTaskMem(lparam);
                //Release the device context handle obtained by a previous call            e.Graphics.ReleaseHdc(hdc);
                //Return last + 1 character printer
                return res.ToInt32();
            }