C# 从下至上将图像拆分为多个图像

C# 从下至上将图像拆分为多个图像,c#,image,winforms,bitmap,rectangles,C#,Image,Winforms,Bitmap,Rectangles,我有一张照片要打印,但是一页太大了 所以我决定把它分成多张图片 我尝试过一种方法,但现在我正在使用(塔尔哈·伊尔凡回答) 我也尝试了其他的解决方案,但效果不太好 (例如,bm.Clone(rec,bm.PixelFormat);) 这是我的代码(这是在非表单类上) 和setImage函数(以某种形式) 而cropImg与cropAtRect 下图显示了原始图像(在左侧) 蓝色矩形中显示想要的结果 右边是实际结果 PS 我的实际图像大小是(高度=698,宽度=576) 编辑-如下所示 论非形式类

我有一张照片要打印,但是一页太大了 所以我决定把它分成多张图片 我尝试过一种方法,但现在我正在使用(塔尔哈·伊尔凡回答) 我也尝试了其他的解决方案,但效果不太好 (例如,
bm.Clone(rec,bm.PixelFormat);

这是我的代码(这是在非表单类上)

和setImage函数(以某种形式)

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();
    }
在形式课上

 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();
    }
将始终尝试绘制整个控件或窗体,并始终从顶部开始。参数:

目标边界 类型:System.Drawing.Rectangle

The bounds within which the control is rendered.
顾名思义,设置的是目标,而不是矩形。因此,结果上方有空白

在裁剪之前,使用保留整个区域的矩形移动直线,可能如下所示:

DrawToBitmap(bm, ClientRectangle);
然后像以前一样修剪下半部分

请注意,链接中的裁剪技巧对
DrawToBitmap
不起作用;使用具有负偏移量的矩形将导致参数异常


顺便说一句:要安全地处理PictureBox中的位图,请使用以下方法:

Bitmap dummy = (Bitmap )somePictureBox.Image;
somePictureBox.Image = null;
if (dummy != null) dummy.Dispose;
事实上,ChrisJJ在链接中的答案泄露了
图形
对象


更新:

由于您似乎已经失去了对各种更改和建议的控制,下面是对原始帖子的最小代码更改:

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


cropImg
函数中,在返回之前添加
g.Dispose

很高兴知道,你有问题吗?我希望右边的结果像左边的正方形,不是很明显吗?你可能是指ChrisJJ的答案。我不知道你为什么会使用这个答案,也看不出你实际上a)使用了类似的值b)真的想要裁剪。您需要的是带有两个矩形的DrawImage重载。我还建议重新考虑打印屏幕副本的想法,因为这通常只有有限的质量。@TaW打印质量对MEP来说并不重要不要忘记处理位图,内存泄漏将是一个问题。DrawToBitmap去哪里了?它需要表单(或控件)的屏幕截图,但如果没有它,则无法显示任何内容。。另外:当位图显示在PictureBox中时,您不能处理它。最好在你再次设置它之前保持警惕。如果我在创建rec后立即绘制ToBitmap,我仍然看不到任何东西,你需要显示你使用的代码。我测试了我对原始代码提出的修改,效果很好。你能发布你的完整答案吗
public void setImage()
{
   Bitmap dummy = pictureBox3.BackgroundImage;
   pictureBox3.BackgroundImage = null;
   if (dummy != bnull) dummy.Dispose();
   pictureBox3.BackgroundImage = _img;       
   this.ShowDialog();
}