主要问题在这一行:
for (int i = 1; i <= (int)(this.Height / m); i++)
▶this.Height显然不是你想写的,我们换成Image.Height吧
▶ grp.DrawLine(Pens.Red, x, y); 和 grp.DrawLine(new Pen(Color.Red, 5f), x, y); 将绘制不同大小的线条(1 和 5 像素)。在示例代码中,这两个方法接受定义 Pen 颜色和大小的 Color 和 float 参数。
▶grp.SmoothingMode:我们这里不需要任何平滑模式,不需要画直线,它会添加清晰可见的抗锯齿,尤其是当保存为JPEG格式的图像时(它会抗锯齿)别名 - 有点,它实际上会破坏颜色 - 这些线条本身)。
▶ 您不会处理您创建的任何 Graphics 对象。这对于频繁的图形操作和处理大型位图都非常重要。
Pen 和 Graphics 对象需要被释放。
由于尚不清楚是否要生成在两个维度上具有相同行数的网格 - 因此,最有可能的是,具有宽度不等于高度的单元格的网格 - 或者具有平方单元格(这是示例图像似乎显示的内容,而不是代码),我发布了两种绘制两种网格类型的方法:
第一种方法,宽高行数相同:
var gridSizeX = (float)image.Width / lines;
var gridSizeY = (float)image.Height / lines;
private Image DrawGridLines(int lines, string imgPath, Color penColor, float penSize)
{
var image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imgPath)), true);
using (var g = Graphics.FromImage(image)) {
g.PixelOffsetMode = PixelOffsetMode.Half;
var gridSizeX = (float)image.Width / lines;
var gridSizeY = (float)image.Height / lines;
for (int i = 1; i < lines; i++) {
var pointX1 = new PointF(0, i * gridSizeY);
var pointX2 = new PointF(image.Width, i * gridSizeY);
var pointY1 = new PointF(i * gridSizeX, 0);
var pointY2 = new PointF(i * gridSizeX, image.Height);
using (var pen = new Pen(penColor, penSize)) {
g.DrawLine(pen, pointX1, pointX2);
g.DrawLine(pen, pointY1, pointY2);
}
}
return image;
}
}
第二种方法,画一个方格。整数值gridSection,用于根据位图的最小尺寸定义网格单元。
然后使用该维度来确定要在另一个维度中绘制多少条线。
网格大小是在最小维度上计算的:
var gridSize = (float)Math.Min(image.Width, image.Height) / gridSection;
Cell 被确定为一个结果:
var gridStepMin = Math.Min(image.Width, image.Height) / gridSize;
var gridStepMax = Math.Max(image.Width, image.Height) / gridSize;
private Image DrawSquaredGrid(int gridSection, string imgPath, Color penColor, float penSize)
{
var image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imgPath)), true);
using (var g = Graphics.FromImage(image)) {
g.PixelOffsetMode = PixelOffsetMode.Half;
var gridSize = (float)Math.Min(image.Width, image.Height) / gridSection;
var gridStepMin = Math.Min(image.Width, image.Height) / gridSize;
var gridStepMax = Math.Max(image.Width, image.Height) / gridSize;
for (int i = 1; i < gridStepMin; i++) {
var pointY1 = new PointF(i * gridSize, 0);
var pointY2 = new PointF(i * gridSize, image.Height);
using (var pen = new Pen(penColor, penSize)) {
g.DrawLine(pen, pointY1, pointY2);
}
}
for (int i = 1; i < gridStepMax; i++) {
var pointX1 = new PointF(0, i * gridSize);
var pointX2 = new PointF(image.Width, i * gridSize);
using (var pen = new Pen(penColor, penSize)) {
g.DrawLine(pen, pointX1, pointX2);
}
}
return image;
}
}
SaveFileDialog 被重构以允许多种图像格式。并根据选择调用其中一种绘图方法(在示例代码中,使用 CheckBox (chkSquared) 选择其中一种 Grid 类型)。
您可以添加更多格式,ImageFormatFromFileName() 方法根据SaveFileDialog.FielName 扩展名选择ImageFormat 类型。
private void BtnExportClick(object sender, EventArgs e)
{
string imagePath = [Some Path];
using (var sfd = new SaveFileDialog()) {
sfd.Filter = "PNG Image (*.png)|*.png|TIFF Image (*.tif)|*.tif|JPEG Image (*.jpg)|*.jpg";
sfd.RestoreDirectory = true;
sfd.AddExtension = true;
if (sfd.ShowDialog() == DialogResult.OK) {
Image image = null;
if (chkSquared.Checked) {
image = DrawSquaredGrid((int)numericUpDown1.Value, imagePath, Color.Red, 5.0f);
}
else {
image = DrawGridLines((int)numericUpDown1.Value, imagePath, Color.Red, 5.0f);
}
image.Save(sfd.FileName, ImageFormatFromFileName(sfd.FileName));
MessageBox.Show("Done");
image.Dispose();
}
}
}
private ImageFormat ImageFormatFromFileName(string fileName)
{
string fileType = Path.GetExtension(fileName).Remove(0, 1);
if (fileType.Equals("tif")) fileType = "tiff";
if (fileType.Equals("jpg")) fileType = "jpeg";
return (ImageFormat)new ImageFormatConverter().ConvertFromString(fileType);
}