разделить изображение на несколько изображений снизу вверх - PullRequest
0 голосов
/ 17 мая 2018

У меня есть фотография, которую я хочу напечатать, но она слишком велика для одной страницы поэтому я решил разделить его на несколько изображений Я попробовал метод, но теперь я использую это (ответ Талха Ирфан) я также попробовал другие решения там, но те не работали также (напр. bm.Clone(rec, bm.PixelFormat);)

и вот мой код (это не в классе)

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

и функция setImage (в некоторой форме)

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

и cropImg совпадают с cropAtRect

ниже показано исходное изображение (слева) желаемый результат в синем прямоугольнике а фактический результат справа

PS мой фактический размер изображения (высота = 698, wifht = 576)

Изменить - как предложено ниже

на неформальном классе

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

в классе

  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

1 Ответ

0 голосов
/ 17 мая 2018

Control.DrawToBitmap всегда будет пытаться нарисовать весь элемент управления или форму и всегда будет начинаться сверху.Параметр:

targetBounds Тип: System.Drawing.Rectangle

The bounds within which the control is rendered.

, как следует из названия, устанавливает target , а не источник прямоугольник.Отсюда пробел над вашим результатом.

Переместите линию перед кадрированием с помощью прямоугольника, который содержит всю область, возможно, так:

DrawToBitmap(bm, ClientRectangle);

, а затем обрежьте нижнюю часть, как и раньше..

Обратите внимание, что уловка обрезки по вашей ссылке не будет работать для DrawToBitmap;использование прямоугольника с отрицательным смещением вызовет исключение параметра.


Кстати: для безопасного удаления растрового изображения в PictureBox используйте следующее:

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

И, действительно,ответ ChrisJJ в ссылке утечка объекта Graphics.


Обновление:

Поскольку вы, кажется, потеряли контроль над различными изменениями и предложениями, вот минимальное изменение кода по сравнению с исходным сообщением:

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

С помощью:

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

В функции cropImg добавьте g.Dispose перед возвратом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...