Hi !
I'm writing code to draw points on an image whose coordinates come from a datagridview. For this I import an image in a picturebox, I select two rows of the datagridview then select these two points on the image in order to define the scale.
Depending on the imported image I get different results, sometimes the scale is not the right one, sometimes there is a distortion of the drawn points.
If anyone has any idea, here is my code.
Thank you all!
I'm writing code to draw points on an image whose coordinates come from a datagridview. For this I import an image in a picturebox, I select two rows of the datagridview then select these two points on the image in order to define the scale.
Depending on the imported image I get different results, sometimes the scale is not the right one, sometimes there is a distortion of the drawn points.
If anyone has any idea, here is my code.
Thank you all!
C#:
public partial class PlanForm : Form
{
public PlanForm()
{
InitializeComponent();
}
private Dictionary<string, Color> designationColors = new Dictionary<string, Color>();
private List<Color> availableColors = new List<Color> { Color.Blue, Color.Green, Color.Red, Color.Yellow, Color.Magenta };
private Image originalPlanImage;
private DataGridViewRow[] selectedRows = null;
private PointF? scaleStartPoint = null;
private PointF? scaleEndPoint = null;
private PointF translation = new PointF(0, 0);
private bool isScaling = false;
private bool isScalingCancelled = false;
private float scaleFactor = 1;
private float imageScaleFactorX = 1;
private float imageScaleFactorY = 1;
private void btnImportPnp_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text Files (*.txt)|*.txt";
openFileDialog.Title = "Import File";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
string[] lines = File.ReadAllLines(filePath);
DataTable dataTable = new DataTable();
dataTable.Columns.Add("R");
dataTable.Columns.Add("D");
dataTable.Columns.Add("X");
dataTable.Columns.Add("Y");
foreach (string line in lines)
{
string[] columns = line.Split('\t');
if (columns.Length == 4)
{
dataTable.Rows.Add(columns);
}
}
dgvPnp.DataSource = dataTable;
DataGridViewCheckBoxColumn checkboxColumn = new DataGridViewCheckBoxColumn();
checkboxColumn.HeaderText = "Visible";
dgvPnp.Columns.Add(checkboxColumn);
}
}
catch (Exception ex)
{
MessageBox.Show($"Error : {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnSelectAllPnp_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dgvPnp.Rows)
{
DataGridViewCheckBoxCell checkBoxCell = row.Cells[4] as DataGridViewCheckBoxCell;
checkBoxCell.Value = true;
}
}
private void btnUnselectAllPnp_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dgvPnp.Rows)
{
DataGridViewCheckBoxCell checkBoxCell = row.Cells[4] as DataGridViewCheckBoxCell;
checkBoxCell.Value = false;
}
}
private void btnImportPlan_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Image (*.png;*.jpg;*.jpeg;*.gif;*.bmp)|*.png;*.jpg;*.jpeg;*.gif;*.bmp";
openFileDialog.Title = "Import Image";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
originalPlanImage = Image.FromFile(openFileDialog.FileName);
pbImport.Image = (Image)originalPlanImage.Clone();
pbImport.SizeMode = PictureBoxSizeMode.StretchImage;
imageScaleFactorX = (float)pbImport.Width / originalPlanImage.Width;
imageScaleFactorY = (float)pbImport.Height / originalPlanImage.Height;
}
}
catch (Exception ex)
{
MessageBox.Show($"Error : {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ColorPlan()
{
if (pbImport.Image == null)
return;
Bitmap planImage = new Bitmap(originalPlanImage);
using (Graphics g = Graphics.FromImage(planImage))
{
foreach (DataGridViewRow row in dgvPnp.Rows)
{
DataGridViewCheckBoxCell checkBoxCell = row.Cells[4] as DataGridViewCheckBoxCell;
if (checkBoxCell.Value != null && (bool)checkBoxCell.Value)
{
string designation = row.Cells["D"].Value.ToString();
float x = (float.Parse(row.Cells["X"].Value.ToString()) * scaleFactor + translation.X) / imageScaleFactorX;
float y = pbImport.Image.Height - (float.Parse(row.Cells["Y"].Value.ToString()) * scaleFactor + translation.Y) / imageScaleFactorY;
Color color = GetDesignationColor(designation);
using (Brush brush = new SolidBrush(color))
{
g.FillEllipse(brush, x - 5, y - 5, 10, 10);
}
}
}
}
pbImport.Image = planImage;
}
private Color GetDesignationColor(string designation)
{
if (!designationColors.ContainsKey(designation))
{
Color color = availableColors[designationColors.Count % availableColors.Count];
designationColors.Add(designation, color);
}
return designationColors[designation];
}
private void btnStartScale_Click(object sender, EventArgs e)
{
if (dgvPnp.SelectedRows.Count != 2)
{
MessageBox.Show("Please select two rows.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
selectedRows = new DataGridViewRow[] { dgvPnp.SelectedRows[0], dgvPnp.SelectedRows[1] };
isScaling = true;
isScalingCancelled = false;
scaleStartPoint = null;
scaleEndPoint = null;
}
private void pbImport_MouseDown(object sender, MouseEventArgs e)
{
if (isScaling && !isScalingCancelled)
{
float scaledX = e.X / imageScaleFactorX;
float scaledY = e.Y / imageScaleFactorY;
if (scaleStartPoint == null)
{
scaleStartPoint = new PointF(scaledX, scaledY);
}
else if (scaleEndPoint == null)
{
scaleEndPoint = new PointF(scaledX, scaledY);
CalculateScaleFactor();
isScaling = false;
}
}
}
private void CalculateScaleFactor()
{
float x1 = float.Parse(selectedRows[0].Cells["X"].Value.ToString());
float y1 = float.Parse(selectedRows[0].Cells["Y"].Value.ToString());
float x2 = float.Parse(selectedRows[1].Cells["X"].Value.ToString());
float y2 = float.Parse(selectedRows[1].Cells["Y"].Value.ToString());
float knownDistanceMM = (float)Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
float pixelDistance = (float)Math.Sqrt(
Math.Pow((scaleEndPoint.Value.X * imageScaleFactorX) - (scaleStartPoint.Value.X * imageScaleFactorX), 2) +
Math.Pow((scaleEndPoint.Value.Y * imageScaleFactorY) - (scaleStartPoint.Value.Y * imageScaleFactorY), 2));
scaleFactor = pixelDistance / knownDistanceMM;
translation.X = (scaleStartPoint.Value.X * imageScaleFactorX) - (x1 * scaleFactor);
translation.Y = (scaleStartPoint.Value.Y * imageScaleFactorY) - (y1 * scaleFactor);
}
private void btnGenerer_Click(object sender, EventArgs e)
{
ColorPlan();
}
private void trackBarX_ValueChanged(object sender, EventArgs e)
{
translation.X = trackBarX.Value;
ColorPlan();
}
private void trackBarY_ValueChanged(object sender, EventArgs e)
{
translation.Y = trackBarY.Value;
ColorPlan();
}
private void btnCancelScale_Click(object sender, EventArgs e)
{
isScaling = false;
isScalingCancelled = true;
scaleStartPoint = null;
scaleEndPoint = null;
}
}