从 txt 文件绘制线条到图像。笔粗过大。
Drawing lines to image from a txt file. Pen thickness is too large.
让我描述一个问题,到目前为止我花了一天多的时间才解决这个问题。我正在从一个文本文件中输入一系列的行,我想用它们画一幅画。问题是这些线中的两条太近了(1 像素距离),如果使用 Pen of Thickness is=1,这就是一个问题。请参阅下面的问题区域:
供参考,文本文件中表示整个形状的线条的边界矩形如下:
Rectangle(xmin, ymin, (xmax - xmin), (ymax - ymin)) = 761, 236, 298, 344
我正在尝试将它们绘制成 Bitmap(20000, 15000)
,但如果需要,可以更改位图的大小。
我的问题是:
- 有没有办法让笔的粗细小于 1 到
避免这种重叠?
- 是否可以修改输入
协调一点(某种“扩张”)所以这个问题
不会发生?
否则,有人可以想出另一种解决方案来解决这个问题吗?
非常感谢,
我的代码:
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace DrawingLinesTest
{
class Program
{
static void Main(string[] args)
{
//Define the input txt file
System.IO.StreamReader file = new System.IO.StreamReader("input.txt");
//Define the bmp
Bitmap bmp = new Bitmap(20000, 15000);
Graphics g = Graphics.FromImage(bmp);
Pen blackPen = new Pen(Color.FromArgb(255, 0, 0, 0), 1);
// Read the file
int counter = 0;
string line;
var listX1 = new List<int>();
var listY1 = new List<int>();
var listX2 = new List<int>();
var listY2 = new List<int>();
var allPoints = new List<Point>();
while ((line = file.ReadLine()) != null)
{
string[] points = line.Split(',');
int x1 = int.Parse(points[0]), y1 = int.Parse(points[1]), x2 = int.Parse(points[2]), y2 = int.Parse(points[3]);
int[] pInt = new int[4] { x1, y1, x2, y2 };
listX1.Add(x1); listY1.Add(y1); listX2.Add(x2); listY2.Add(y2);
Point a = new Point(int.Parse(points[0]), int.Parse(points[1]));
Point b = new Point(int.Parse(points[2]), int.Parse(points[3]));
allPoints.Add(a); allPoints.Add(b);
g.DrawLine(blackPen, a, b);
counter++;
}
file.Close();
g.Dispose();
//-----------------------------------------------------------------------------------------------------------------------------------------------
// Find the list's bounding box.
IEnumerable<Point> po = allPoints;
Rectangle r = BoundingBox(po);
Console.WriteLine(String.Format("Bounding Box {0},{1},{2},{3}", r.X, r.Y, r.Width, r.Height));
Bitmap nb = new Bitmap(r.Width, r.Height);
Graphics gr = Graphics.FromImage(nb);
gr.DrawImage(bmp, -r.X, -r.Y);
//Save input file as an image (output)
nb.Save("outputPicture.png");
//-----------------------------------------------------------------------------------------------------------------------------------------------
}
public static Rectangle BoundingBox(IEnumerable<Point> points)
{
var x_query = from Point p in points select p.X;
int xmin = x_query.Min();
int xmax = x_query.Max();
var y_query = from Point p in points select p.Y;
int ymin = y_query.Min();
int ymax = y_query.Max();
return new Rectangle(xmin, ymin, (xmax - xmin), (ymax - ymin)); }
}//end Program
}//end Namespace
一些背景:
在图形中你必须处理几个坐标系:
- 世界坐标,例如以米为单位。在您的情况下,这些是文本文件中的坐标
- Canvas坐标/位图坐标,通常以像素为单位,这些是生成图像中的像素。
然后你有一些从世界坐标到 canvas 坐标的坐标转换。你省略了这一步,这会产生你的问题。
如果您为世界中的 1 个单位创建坐标转换 -> 10 个像素,所有问题都会消失。
编辑
在您的情况下,乘以 10 即可:
Point a = new Point(int.Parse(points[0]*10), int.Parse(points[1]*10));
Point b = new Point(int.Parse(points[2]*10), int.Parse(points[3]*10));
让我描述一个问题,到目前为止我花了一天多的时间才解决这个问题。我正在从一个文本文件中输入一系列的行,我想用它们画一幅画。问题是这些线中的两条太近了(1 像素距离),如果使用 Pen of Thickness is=1,这就是一个问题。请参阅下面的问题区域:
供参考,文本文件中表示整个形状的线条的边界矩形如下:
Rectangle(xmin, ymin, (xmax - xmin), (ymax - ymin)) = 761, 236, 298, 344
我正在尝试将它们绘制成 Bitmap(20000, 15000)
,但如果需要,可以更改位图的大小。
我的问题是:
- 有没有办法让笔的粗细小于 1 到 避免这种重叠?
- 是否可以修改输入 协调一点(某种“扩张”)所以这个问题 不会发生?
否则,有人可以想出另一种解决方案来解决这个问题吗?
非常感谢,
我的代码:
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace DrawingLinesTest
{
class Program
{
static void Main(string[] args)
{
//Define the input txt file
System.IO.StreamReader file = new System.IO.StreamReader("input.txt");
//Define the bmp
Bitmap bmp = new Bitmap(20000, 15000);
Graphics g = Graphics.FromImage(bmp);
Pen blackPen = new Pen(Color.FromArgb(255, 0, 0, 0), 1);
// Read the file
int counter = 0;
string line;
var listX1 = new List<int>();
var listY1 = new List<int>();
var listX2 = new List<int>();
var listY2 = new List<int>();
var allPoints = new List<Point>();
while ((line = file.ReadLine()) != null)
{
string[] points = line.Split(',');
int x1 = int.Parse(points[0]), y1 = int.Parse(points[1]), x2 = int.Parse(points[2]), y2 = int.Parse(points[3]);
int[] pInt = new int[4] { x1, y1, x2, y2 };
listX1.Add(x1); listY1.Add(y1); listX2.Add(x2); listY2.Add(y2);
Point a = new Point(int.Parse(points[0]), int.Parse(points[1]));
Point b = new Point(int.Parse(points[2]), int.Parse(points[3]));
allPoints.Add(a); allPoints.Add(b);
g.DrawLine(blackPen, a, b);
counter++;
}
file.Close();
g.Dispose();
//-----------------------------------------------------------------------------------------------------------------------------------------------
// Find the list's bounding box.
IEnumerable<Point> po = allPoints;
Rectangle r = BoundingBox(po);
Console.WriteLine(String.Format("Bounding Box {0},{1},{2},{3}", r.X, r.Y, r.Width, r.Height));
Bitmap nb = new Bitmap(r.Width, r.Height);
Graphics gr = Graphics.FromImage(nb);
gr.DrawImage(bmp, -r.X, -r.Y);
//Save input file as an image (output)
nb.Save("outputPicture.png");
//-----------------------------------------------------------------------------------------------------------------------------------------------
}
public static Rectangle BoundingBox(IEnumerable<Point> points)
{
var x_query = from Point p in points select p.X;
int xmin = x_query.Min();
int xmax = x_query.Max();
var y_query = from Point p in points select p.Y;
int ymin = y_query.Min();
int ymax = y_query.Max();
return new Rectangle(xmin, ymin, (xmax - xmin), (ymax - ymin)); }
}//end Program
}//end Namespace
一些背景:
在图形中你必须处理几个坐标系:
- 世界坐标,例如以米为单位。在您的情况下,这些是文本文件中的坐标
- Canvas坐标/位图坐标,通常以像素为单位,这些是生成图像中的像素。
然后你有一些从世界坐标到 canvas 坐标的坐标转换。你省略了这一步,这会产生你的问题。
如果您为世界中的 1 个单位创建坐标转换 -> 10 个像素,所有问题都会消失。
编辑
在您的情况下,乘以 10 即可:
Point a = new Point(int.Parse(points[0]*10), int.Parse(points[1]*10));
Point b = new Point(int.Parse(points[2]*10), int.Parse(points[3]*10));