richtextbox - how to save drew Graphics of "Paint()" into image using c#? -


(sorry if post duplicate or ...)

i wanted convert rtf image after googling lot i've got code paint() event of picturebox1 , works :

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 create 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"); } 

my app

in picture above left richtextbox , right picturebox.

the issue don't know how save paint() drew graphic file.because 3 last lines of code save empty image.

any appreciated?

update #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); 

by changing graphics e.graphics g issue resolved 1 other issue quality of bitmap low. i've added bunch of code i've got same result, quality low! suggestions?

update #2

here graphics_drawrtftext class conversion :

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 code found here: http://support.microsoft.com/kb/812425/en-us          //convert unit used .net framework (1/100 inch)          //and unit used win32 api calls (twips 1/1440 inch)         private const double aninch = 14.4;          protected override createparams createparams         {                         {                 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 area 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 character              fmtrange.chrg.cpmin = 0;             fmtrange.hdc = hdc;                                //use same dc measuring , rendering             fmtrange.hdctarget = hdc;                    //point @ printer hdc             fmtrange.rc = rectlayoutarea;            //indicate area on page print             fmtrange.rcpage = rectlayoutarea;    //indicate size of page              intptr wparam = intptr.zero;             wparam = new intptr(1);              //get pointer 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 block of memory allocated             marshal.freecotaskmem(lparam);              //release device context handle obtained 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 start of doc)                 public int cpmax;        //last character of range (-1 end of doc)             }              [structlayout(layoutkind.sequential)]             public struct formatrange             {                 public intptr hdc;                //actual dc draw on                 public intptr hdctarget;    //target dc determining text formatting                 public rect rc;                        //region of dc draw (in twips)                 public rect rcpage;                //region of whole dc (page size) (in twips)                 public charrange chrg;        //range of text 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     } } 

disclaimer: don't have time dig posted extension method interesting , works well, @ least when drawing onto control surface.

but reproduce how bad results when drawing bitmap..

but: when done right saved results excellent!

so here here few things keep in mind:

  • saving in paint event bad idea, event triggered system whenever needs redraw control; test doing minimize/maximize cycle.

  • in addition drawrtftext semms create double-vision effect when drawing bitmap.

  • so make sure use drawtobitmap grab results. need place call drawrtftext in paint event of control!

  • also make sure have large enough resolutions both in control (pixel size) , bitmap (dpi) nice, crispy , (if needed) printable results.

  • do not save jpg bound result in blurry text! png format of choice!

here paint event:

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 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);              } 

note pays improve on default quality settings; if don't text in resulting file break apart when zooming in..

here save button click:

private void button1_click(object sender, eventargs e) {     size sz = panel1.clientsize;      // first (optionally) create bitmap in 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);      // create 4x larger one:     rectangle rect2 = new rectangle(0, 0, sz.width * 4, sz.height * 4);     bitmap bmp2 = new bitmap(rect2.width, rect2.height);      // need temporarily enlarge panel:     panel1.clientsize = rect2.size;      // can let routine draw     panel1.drawtobitmap(bmp2, rect2);     // , before saving optionally can set dpi resolution     bmp2.setresolution(300, 300);      // optionally make background transparent:     bmp2.maketransparent(richtextbox1.backcolor);     unsemi(bmp2);  // see link in comment!      // save text png; jpg fotos!     bmp2.save("d:\\rtfimage2.png", imageformat.png);      // restore panels size     panel1.clientsize = sz; } 

i found result good.

note drawtobitmap internally trigger paint event grab drawn graphics.

of course don't need both parts - use 1 want (.e. skip 1st part, between first , now ) , use own numbers. helps know output shall , calculate necessary sizes , resolutions backward there.

i added enlarged version because monitor resolution, controls have, rather limited, around 75-100dpi, while print quality starts @ 150dpi..

enter image description hereenter image description here

here link unsemi function


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -