How to save drew Graphics of “Paint()” into image using c#?

前端 未结 2 1229
深忆病人
深忆病人 2021-01-16 22:26

I actually wanted to Convert RTF into Image so after googling a lot I\'ve got a code that does it by Paint() Event of Picturebox1 and it works perfectly : <

2条回答
  •  执笔经年
    2021-01-16 23:05

    Disclaimer: I don't have the time to dig into the posted extension method but it is interesting and works well, at least when drawing onto a control surface.

    But I could reproduce how bad the results are when drawing into a bitmap..

    But: When done right the saved results are excellent!

    So here here are a few things to keep in mind:

    • Saving in the Paint event is a bad idea, as this event will be triggered by the system whenever it needs to redraw the control; test by doing a minimize/maximize cycle.

    • In addition the DrawRtfText semms to create a double-vision effect when drawing into a bitmap.

    • So make sure you use DrawToBitmap to grab the results. For this you need to place the call to DrawRtfText in the Paint event of a control!

    • Also make sure to have large enough resolutions both in the control (pixel size) and the Bitmap (dpi) to get nice, crispy and (if needed) printable results.

    • Do not save to jpg as this is bound to result in blurry text! Png is the format of choice!

    Here is a 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 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);            
            
    }
    

    Note that it pays to improve on the default quality settings; if you don't the text in the resulting file will break apart when zooming in..

    Here is a Save button click:

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

    I found the result to be really good.

    Note that DrawToBitmap will internally trigger the Paint event to grab the drawn graphics.

    Of course you don't need both parts - use only the one you want (.e. skip the 1st part, between first and now ) and do use your own numbers. It helps to know what the output shall be and calculate the necessary sizes and resolutions backward from there.

    I added the enlarged version because usually the monitor resolution, which is what the controls all have, is rather limited, around 75-100dpi, while print quality starts only at 150dpi..

    Here is a link to the UnSemi function

提交回复
热议问题