разделяне на изображение на множество изображения отдолу нагоре

Имам снимка, която искам да отпечатам, но е твърде голяма за една страница, така че реших да я разделя на няколко изображения, опитах метод, но сега използвам this (отговор на Талха Ирфан) Опитах и ​​другите решения там, но те също не работеха (напр. 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, ширина = 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();
    }

въведете описание на изображението тук


person styx    schedule 17.05.2018    source източник
comment
Чудесно е да знам, имате ли въпрос?   -  person Trey    schedule 17.05.2018
comment
искам резултатът отдясно да бъде като квадрата отляво, не е ли очевидно?   -  person styx    schedule 17.05.2018
comment
Вероятно имаш предвид отговора на ChrisJJ. Не съм сигурен защо бихте използвали този отговор, нито виждам, че всъщност а) използвате подобни стойности б) наистина искате да изрежете. Това, което искате, е претоварването на DrawImage с два правоъгълника. Също така препоръчвам да преосмислите идеята за отпечатване на екранно копие, тъй като това обикновено ще има само ограничено качество.   -  person TaW    schedule 17.05.2018
comment
@TaW качеството на печат няма значение за мен   -  person styx    schedule 17.05.2018
comment
Не, не беше ясно. Добре, първо не използвайте frmPrint.DrawToBitmap. Създайте ново растерно изображение с целевия размер. След това използвайте клониране, за да копирате правоъгълници от изходното растерно изображение, НЕ формуляра. Начертайте новото изображение върху новия формуляр. Отпечатайте, повторете. Ако имате конкретни проблеми, мога да помогна с отговор.   -  person Trey    schedule 17.05.2018
comment
ps не забравяйте да изхвърлите растерните изображения, изтичането на памет ще бъде проблем.   -  person Trey    schedule 17.05.2018
comment
@Trey и аз редактирахме въпроса ми, но сега виждам празен екран   -  person styx    schedule 17.05.2018


Отговори (1)


Control.DrawToBitmap винаги ще се опитва да начертае цялата контрола или формуляр и винаги ще започва отгоре. Параметърът:

targetBounds Тип: System.Drawing.Rectangle

The bounds within which the control is rendered.

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

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

DrawToBitmap(bm, ClientRectangle);

и след това изрежете долната част както преди..

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


Между другото: за безопасно изхвърляне на Bitmap в 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 преди връщане.

person TaW    schedule 17.05.2018
comment
Къде изчезна DrawToBitmap? Необходима е екранна снимка на формата (или контрола), но без нея нищо не може да се покаже.. Също така: Докато растерна графика е показана в PictureBox, не трябва да я изхвърляте. Най-добре изчакайте, докато го настроите отново.. - person TaW; 17.05.2018
comment
ако направя DrawToBitmap веднага след създаването на rec, все още не виждам нищо - person styx; 17.05.2018
comment
Трябва да покажете кода, който използвате. Тествах промените, които предложих в оригиналния код и те работят добре. - person TaW; 17.05.2018
comment
можете ли да публикувате пълния си отговор, изглежда, че правите нещо глупаво и не го осъзнавам - person styx; 17.05.2018