C#实现图片对半分割并显示到PictureBox的问题求助
图片对半分割问题(C# VS2022)
我是C#新手,使用Visual Studio 2022,想要把一张图片对半分割,然后把分割后的两张图分别显示到两个PictureBox里。我已经能成功把完整图片加载到PictureBox,代码如下:
FileStream myFileStream = new FileStream(imagepath, FileMode.Open, FileAccess.Read); MemoryStream myStream = new MemoryStream(); byte[] photo = new byte[myFileStream.Length]; myFileStream.Read(photo, 0, photo.Length); myStream.Write(photo, 0, photo.Length); drawingImage = new Bitmap(myStream); // 无错误
之后我尝试通过读取一半字节流的方式分割图片,修改后的代码如下,但创建Bitmap时抛出System.ArgumentException:"Invalid parameter."错误:
byte[] photo = new byte[myFileStream.Length / 2]; // 只取一半长度 myFileStream.Read(photo, 0, photo.Length); // 我以为这样就能只读取一半内容 myStream.Write(photo, 0, photo.Length); drawingImage = new Bitmap(myStream); // 报错:System.ArgumentException:"Invalid parameter."
我的最终目标是分割大容量图片,请问该如何解决这个问题?
解决方案
直接分割图片的字节流行不通,因为JPG、PNG这类图片文件有特定的格式结构,只取一半字节会破坏文件的格式信息,导致Bitmap无法识别。正确的做法是先完整加载图片,再通过GDI+对图像进行裁剪分割,这种方法也能应对大容量图片,只要合理处理资源释放即可。
步骤1:完整加载图片(优先用自动释放资源的写法)
// 用using包裹,确保图片资源自动释放,避免内存泄漏 using (Image originalImage = Image.FromFile(imagepath)) { // 后续分割操作写在这里 }
步骤2:裁剪左右两半(水平分割)
using (Image originalImage = Image.FromFile(imagepath)) { int halfWidth = originalImage.Width / 2; int fullHeight = originalImage.Height; // 裁剪左半部分 using (Bitmap leftBitmap = new Bitmap(halfWidth, fullHeight)) { using (Graphics g = Graphics.FromImage(leftBitmap)) { // 从原图左上角开始,截取宽度为halfWidth的区域,绘制到左半边位图 g.DrawImage(originalImage, new Rectangle(0, 0, halfWidth, fullHeight), new Rectangle(0, 0, halfWidth, fullHeight), GraphicsUnit.Pixel); } // 克隆后再赋值给PictureBox,避免using释放后图片失效 pictureBox1.Image = (Image)leftBitmap.Clone(); } // 裁剪右半部分 using (Bitmap rightBitmap = new Bitmap(halfWidth, fullHeight)) { using (Graphics g = Graphics.FromImage(rightBitmap)) { // 从原图的halfWidth位置开始截取右半边区域 g.DrawImage(originalImage, new Rectangle(0, 0, halfWidth, fullHeight), new Rectangle(halfWidth, 0, halfWidth, fullHeight), GraphicsUnit.Pixel); } pictureBox2.Image = (Image)rightBitmap.Clone(); } }
步骤2:裁剪上下两半(垂直分割)
如果需要垂直分割,只需要调整高度参数和截取区域:
using (Image originalImage = Image.FromFile(imagepath)) { int fullWidth = originalImage.Width; int halfHeight = originalImage.Height / 2; // 裁剪上半部分 using (Bitmap topBitmap = new Bitmap(fullWidth, halfHeight)) { using (Graphics g = Graphics.FromImage(topBitmap)) { g.DrawImage(originalImage, new Rectangle(0, 0, fullWidth, halfHeight), new Rectangle(0, 0, fullWidth, halfHeight), GraphicsUnit.Pixel); } pictureBox1.Image = (Image)topBitmap.Clone(); } // 裁剪下半部分 using (Bitmap bottomBitmap = new Bitmap(fullWidth, halfHeight)) { using (Graphics g = Graphics.FromImage(bottomBitmap)) { g.DrawImage(originalImage, new Rectangle(0, 0, fullWidth, halfHeight), new Rectangle(0, halfHeight, fullWidth, halfHeight), GraphicsUnit.Pixel); } pictureBox2.Image = (Image)bottomBitmap.Clone(); } }
大容量图片优化建议
- 全程用
using包裹Image、Bitmap、Graphics对象,确保资源及时释放,避免内存堆积 Image.FromFile本身会做内存优化,不会一次性把所有像素加载到内存,除非你主动锁定像素,所以常规大容量图片用上面的方法完全没问题- 如果是超大规模图片(比如数亿像素),可以考虑用Windows Imaging Component(WIC)的分块处理API,但新手阶段上面的方法足够覆盖绝大多数场景
内容的提问来源于stack exchange,提问作者RANG MIHO
相关产品推荐
相关产品推荐

