0

I have a picture I want to print, but it's too big for one page so i have decided to split it into multiple images i have tried a method, but now im using this (Talha Irfan answer) i also tried the other solutions there but those didnt worked as well (ex. bm.Clone(rec, bm.PixelFormat);)

and here's my code(this is on non-form class)

  Bitmap bm = new Bitmap(frmPrint.Width, frmPrint.Height);
  Rectangle rec = new Rectangle(0, 200, 576, 300); 
  Bitmap bitmap = cropImg(bm, rec);   

 frmPrint.DrawToBitmap(bitmap, rec);
 frmPrint._img = bitmap;
 frmPrint.setImage();

and setImage function(on some form)

  public void setImage()
  {
      pictureBox3.BackgroundImage = _img;       
      this.ShowDialog();
  }

and cropImg is the same as cropAtRect

the below shows the original image (on the left) the wanted result in the blue rectangle and the actual result on the right

PS my actual image size is (height = 698, wifht = 576)

Edit - as suggested below

on non-form class

 Rectangle cropRect = new Rectangle(0, 0, 576, 698); 
  Bitmap target = new Bitmap(cropRect.Width, cropRect.Height, bm.PixelFormat);
  frmPrint.setImage(bm, target, cropRect);
  target.Dispose();

at form class

  public void setImage(Bitmap src, Bitmap target, Rectangle cropRect)
    {


        pictureBox3.Visible = false;
        using (Graphics g = Graphics.FromImage(target))
        {
            g.DrawImage(src, new Rectangle(pictureBox3.Location.X, pictureBox3.Location.Y, target.Width, target.Height),
                             cropRect,
                             GraphicsUnit.Pixel);
        }      
        this.ShowDialog();
    }

enter image description here

styx
  • 1,852
  • 1
  • 11
  • 22
  • Great to know, do you have a question? – Trey May 17 '18 at 14:24
  • i want the result on the right to be like the square on the left, isn't that obvious? – styx May 17 '18 at 14:25
  • You probably mean ChrisJJ's answer. Not sure why you would use that answer nor can I see that you actually a) use similar values b) really want to crop. What you want is the DrawImage overload with two rectangles. I also recommend rethinking the idea to print a screen copy as this will usually have only limited quality. – TaW May 17 '18 at 14:26
  • @TaW the print quality does not matter to me – styx May 17 '18 at 14:31
  • No, it was not clear. OK, first off do not use frmPrint.DrawToBitmap. Create a new bitmap of the targetsize. Then use clone to copy rectangles off the source bitmap, NOT the form. Draw the new image on the new form. Print, repeat. If you are having specific issues, I can help with an answer. – Trey May 17 '18 at 14:53
  • 2
    ps don't forget to dispose of the bitmaps, memory leaks will be an issue. – Trey May 17 '18 at 14:54
  • @Trey and i have edited my question, but now I see blank screen – styx May 17 '18 at 15:09

1 Answers1

1

Control.DrawToBitmap will always try to draw the whole control or form and will always start at the top. The parameter:

targetBounds Type: System.Drawing.Rectangle

The bounds within which the control is rendered.

as the name implies, sets the target, not the source rectangle. Hence the white space above your result.

Move the line before cropping with a rectangle that holds the full area, maybe like this:

DrawToBitmap(bm, ClientRectangle);

and then crop the lower part as before..

Note that the cropping trick from your link will not work for DrawToBitmap; using a rectangle with a negative offset will cause a parameter exception.


Btw: to safely dispose of a Bitmap in a PictureBox use this:

Bitmap dummy = (Bitmap )somePictureBox.Image;
somePictureBox.Image = null;
if (dummy != null) dummy.Dispose;

And, indeed, the answer by ChrisJJ in the link leaks the Graphics object.


Update:

Since you seem to have lost control over the various changes and suggestions, here is the minimal code change from the original post:

Bitmap bm = new Bitmap(frmPrint.ClientWidth, frmPrint.ClientHeight);
DrawToBitmap(bm, frmPrint.ClientRectangle);

Rectangle rec = new Rectangle(0, 200, 576, 300); 
Bitmap bitmap = cropImg(bm, rec);   

frmPrint._img = bitmap;
frmPrint.setImage();

With:

public void setImage()
{
   Bitmap dummy = pictureBox3.BackgroundImage;
   pictureBox3.BackgroundImage = null;
   if (dummy != bnull) dummy.Dispose();
   pictureBox3.BackgroundImage = _img;       
   this.ShowDialog();
}

In the cropImg function add a g.Dispose before returning.

TaW
  • 53,122
  • 8
  • 69
  • 111
  • Where has the DrawToBitmap gone? It takes a screenshot of the form (or a control) but without it nothing can show.. Also: While a bitmap is shown in a PictureBox you must not dispose of it. Best wairt until you set it again.. – TaW May 17 '18 at 15:29
  • if i do DrawToBitmap right after the creation of the rec i still see nothing – styx May 17 '18 at 15:38
  • You need to show the code that you use. I tested the changes I proposed to the original code and they work fine. – TaW May 17 '18 at 15:40
  • can you post your full answer it seems that doing something stupid and im not aware to it – styx May 17 '18 at 15:43