C# GDI+实现九宫格图片的两种方案
本文介绍在C# WinForm中如何使用GDI+将图片切割为九宫格形式。主要包含两种思路:一是在完整图像上直接叠加网格线,适用于预览且无需局部放大;二是调用DrawImage重载函数截取并分别绘制九个区域,结合背景填充实现精确的拼图效果。
方案一:整体绘制叠加网格线
最直观的做法是将原始图片作为整体进行绘制,随后在内存图像或Canvas上覆盖白色线条形成网格视觉效果。这种方法计算简便,但缺点是前景网格会遮挡部分图片内容,且若需支持鼠标悬停局部放大,必须额外维护每个“切片”的位置和尺寸数据。
实现逻辑涉及计算图片显示区域的起始坐标及宽高,通过循环绘制横向和纵向的分隔线。
//假设 pnlCanvas.Width/Height 为控件大小,m_lineWidth 为线宽
m_startX = pnlCanvas.Width / 6;
m_startY = pnlCanvas.Height / 6;
m_imageWidth = pnlCanvas.Width - m_startX * 2;
m_imageHeight = pnlCanvas.Height - m_startY * 2;
e.Graphics.DrawImage(m_image, m_startX, m_startY, m_imageWidth, m_imageHeight);
using (Pen p = new Pen(Brushes.White, m_lineWidth))
{
int stepX = m_imageWidth / 3;
int stepY = m_imageHeight / 3;
for (int i = 1; i < 3; i++)
{
// 绘制垂直线
e.Graphics.DrawLine(p, m_startX + i * stepX, m_startY, m_startX + i * stepX, m_startY + m_imageHeight);
// 绘制水平线
e.Graphics.DrawLine(p, m_startX, m_startY + i * stepY, m_startX + m_imageWidth, m_startY + i * stepY);
}
}
方案二:切分区域独立绘制
利用Graphics类的DrawImage(Image, Rectangle, Rectangle, GraphicsUnit)重载功能,可以指定原图的某个矩形区域映射到目标位置的另一个矩形内。将源图像划分为 $3 \times 3$ 共9个部分,依次将其绘制到预留了间隙的位置,最后补充绘制网格线。
注意事项:由于像素取整误差,直接计算往往会在右侧和底部留下微小的空白缝隙,影响视觉完整性。建议在绘制前使用白色填充整个区域背景,并在最终绘制时微调宽高(如减去2像素)以消除残白。
//计算各项基础参数
m_startX = pnlCanvas.Width / 6 - 2 * m_lineWidth;
m_startY = pnlCanvas.Height / 6 - 2 * m_lineWidth;
m_imageWholeWidth = pnlCanvas.Width - m_startX * 2;
m_imageWholeHeight = pnlCanvas.Height - m_startY * 2;
int srcImageSplittedWidth = m_image.Width / 3;
int srcImageSplittedHeight = m_image.Height / 3;
//考虑线宽占据的空间
int destImageSplittedWidth = (m_imageWholeWidth - 2 * m_lineWidth) / 3;
int destImageSplittedHeight = (m_imageWholeHeight - 2 * m_lineWidth) / 3;
for (int heightIndex = 0; heightIndex < 3; heightIndex++)
{
for (int widthIndex = 0; widthIndex < 3; widthIndex++)
{
g.DrawImage(m_image,
// 目标位置矩形(含间距偏移)
new Rectangle(
m_startX + destImageSplittedWidth * widthIndex + m_lineWidth * widthIndex,
m_startY + destImageSplittedHeight * heightIndex + m_lineWidth * heightIndex,
destImageSplittedWidth, destImageSplittedHeight),
// 源图像对应切片
new Rectangle(srcImageSplittedWidth * widthIndex, srcImageSplittedHeight * heightIndex, srcImageSplittedWidth, srcImageSplittedHeight),
GraphicsUnit.Pixel);
}
}
// 补充绘制中心分隔线
using (Pen p = new Pen(Brushes.White, m_lineWidth))
{
p.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
for (int i = 1; i < 3; i++)
{
g.DrawLine(p, m_startX + destImageSplittedWidth * i + m_lineWidth * i, m_startY, m_startX + destImageSplittedWidth * i + m_lineWidth * i, m_startY + m_imageWholeHeight);
g.DrawLine(p, m_startX, m_startY + i * destImageSplittedHeight + m_lineWidth * i, m_startX + m_imageWholeWidth, m_startY + i * destImageSplittedHeight + m_lineWidth * i);
}
}
为了避免复杂的对齐计算,更稳健的办法是:先用纯色(通常为白色或透明色)填充目标区域背景,再执行上述的切片绘制。这样网格间的背景色会自动填补计算偏差带来的缝隙。
如果仍有边缘微小留白,可以通过调整背景填充的大小来解决。例如将宽度减少2个像素,确保填充完全覆盖边缘。
g.FillRectangle(Brushes.White, m_startX, m_startY, m_imageWholeWidth-2, m_imageWholeHeight-2);
总结
以上就是用C# GDI+绘制九宫格形式图片的详细内容,更多关于C#九宫格图片处理的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









