using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
namespace RangeFinder
{
public partial class frmMain : Form
{
#region Data definition
private float myZoom = 1;
private int startX = 0;
private int startY = 0;
private int movedX = 0;
private int movedY = 0;
private double myMeasure = 0;
private double mySize = 0;
private double myDistance = 0;
private double mySizeScale = .01;
private double myDistanceScale = 1;
private int myMeasureStartX = 0;
private int myMeasureStartY = 0;
private bool horiZontal = true;
private Bitmap myBitmap;
class Camera
{
internal string Factory="";
internal string Model = "";
internal string AliasName = "";
internal string SensorType = "";
internal float SensorWidth = 0;
internal float SensorHeight = 0;
}
private List<Camera> allCameraInfo=new List<Camera> ();
#endregion
#region Loading all Cameras info
public frmMain()
{
InitializeComponent();
loadCameraInfo();
}
private void loadCameraInfo()
{
// Open the file
string dataFile=Application.StartupPath +"\\Data\\camera.lst";
if (System.IO.File.Exists(dataFile))
{
using (System.IO.StreamReader sr = System.IO.File.OpenText(dataFile))
{
string myLine = "";
while ((myLine = sr.ReadLine()) != null)
{
if (!myLine.StartsWith("//") && myLine.Trim() != "")
{
string[] myData;
myData = myLine.Split(new string[] { "," }, StringSplitOptions.None);
try
{
//Add Camera information to list collection
Camera myCameraInfo = new Camera();
myCameraInfo.Factory = myData[0].Trim ();
myCameraInfo.Model = myData[1].Trim ();
myCameraInfo.AliasName = myData[2].Trim ();
myCameraInfo.SensorType = myData[3].Trim();
myCameraInfo.SensorWidth = Convert.ToSingle(myData[4]);
myCameraInfo.SensorHeight = Convert.ToSingle(myData[5]);
allCameraInfo.Add(myCameraInfo);
//Add Camera manufacture to the menu
bool newFactory = true;
foreach (ToolStripMenuItem mi in mnuCamera.DropDownItems )
{
if (mi.Text.Contains(myCameraInfo.Factory)) newFactory = false;
}
if (newFactory)mnuCamera.DropDownItems.Add(myCameraInfo.Factory);
// Add cameral model to the menu
foreach (ToolStripMenuItem mi in mnuCamera.DropDownItems)
{
if (mi.Text.Contains(myCameraInfo.Factory)) mi.DropDownItems.Add(myCameraInfo.Model + (myCameraInfo.AliasName == "" ? "" : " - " + myCameraInfo.AliasName ),null, mnuCamera_Click);
}
}
catch (Exception ) { }
}
}
}
}
}
#endregion
#region Redraw main picture when loading a new picture, moving, zooming ...
private void frmMain_Load(object sender, EventArgs e)
{
RePaint();
}
private void frmMain_Resize(object sender, EventArgs e)
{
RePaint();
}
private void RePaint()
{
try
{
myBitmap = new Bitmap(picMain.Width, picMain.Height);
Graphics g = Graphics.FromImage(myBitmap);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.DrawImage(picSmall.Image,
new Rectangle(0, 0, picMain.Width, picMain.Height),
new Rectangle(startX, startY, (int)(picMain.Width * myZoom), (int)(picMain.Height * myZoom)),
GraphicsUnit.Pixel);
picMain.Image = myBitmap;
}
catch (Exception) {}
}
#endregion
#region Mouse control for moving, selecting, or measuring some parts of image
private void picSmall_MouseDown(object sender, MouseEventArgs e)
{
try
{
startX = picSmall.Image.Width * e.X / picSmall.Width;
startY = picSmall.Image.Height * e.Y / picSmall.Height;
RePaint();
}
catch (Exception) { }
}
private void picMain_MouseDown(object sender, MouseEventArgs e)
{
if (tsbMove.Checked)
{
movedX = e.X;
movedY = e.Y;
}
else
{
myMeasureStartX = e.X;
myMeasureStartY = e.Y;
}
}
private void picMain_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (tsbMove.Checked)
{
startX -= e.X - movedX;
if (startX < 0) startX = 0;
startY -= e.Y - movedY;
if (startY < 0) startY = 0;
movedX = e.X;
movedY = e.Y;
RePaint();
}
else
{
try
{
// measuring the selected part size on the sensor
double xDiff = Math.Abs(myMeasureStartX - e.X) * myZoom * Convert.ToSingle(txtSensorWidth.Text) / Convert.ToSingle(horiZontal ? txtPicWidth.Text : txtPicHeight.Text);
double yDiff = Math.Abs(myMeasureStartY - e.Y) * myZoom * Convert.ToSingle(txtSensorHeight.Text) / Convert.ToSingle(horiZontal ? txtPicHeight.Text : txtPicWidth.Text);
myMeasure = Math.Pow((Math.Pow(xDiff, 2) + Math.Pow(yDiff, 2)), .5);
tssStatusM.Text = "Size on sensor (mm):" + myMeasure.ToString();
// Drawing a red line to show the size of your selection
picMain.Refresh();
Graphics g = picMain.CreateGraphics();
g.ResetClip();
g.DrawLine(new Pen(Color.Red), myMeasureStartX, myMeasureStartY, e.X, e.Y);
}
catch (Exception) { }
}
}
try
{
float Xp = startX + e.X * myZoom;
float Yp = startY + e.Y * myZoom;
float Xm = Xp * Convert.ToSingle(txtSensorWidth.Text) / Convert.ToSingle(horiZontal ? txtPicWidth.Text : txtPicHeight.Text);
float Ym = Yp * Convert.ToSingle(txtSensorHeight.Text) / Convert.ToSingle(horiZontal ? txtPicHeight.Text:txtPicWidth.Text);
tssStatusP.Text = "Position on file (pixel) X:" + Xp.ToString() + " Y:" + Yp.ToString();
tssStatusS.Text= "Position on sensor (mm) X:" + Xm.ToString() + " Y:" + Ym.ToString();
}
catch (Exception) { }
}
#endregion
#region Loading new picture from hard disk and reading Exif info
private void mnuOpen_Click(object sender, EventArgs e)
{
openFileDialog1.FileName = "";
openFileDialog1 .Filter = "All Files|*.*|JPG|*.jpg";
openFileDialog1 .RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
// Load image
Image myImage = Image.FromFile(openFileDialog1.FileName);
picSmall.Image = myImage;
// reset Data of controls
trbZoom.Value = 50;
startX = 0;
startY = 0;
tstDistance.Text = "";
tstSize.Text = "";
tssStatusM.Text = "Size on sensor (mm):";
tssStatusP.Text = "Position on file (pixel):";
tssStatusS.Text = "Position on sensor (mm):";
txtPicFL.Text = "";
txtPicWidth.Text = "";
txtPicHeight.Text = "";
txtCameraFactory.Text = "";
setZoom();
// Get the picture information from the inside of file (EXIF information)
PropertyItem myProperty = myImage.GetPropertyItem(37386);
byte[] l = new byte[myProperty.Len / 2];
byte[] h = new byte[myProperty.Len / 2];
Array.Copy(myProperty.Value, 0, l, 0, myProperty.Len / 2);
Array.Copy(myProperty.Value, myProperty.Len / 2, h, 0, myProperty.Len / 2);
txtPicFL.Text = Convert.ToString((float)convertToInt32U(l) / convertToInt32U(h));
txtPicWidth.Text = myImage.PhysicalDimension.Width.ToString();
txtPicHeight.Text = myImage.PhysicalDimension.Height.ToString();
if (myImage.PhysicalDimension.Width > myImage.PhysicalDimension.Height) horiZontal = true;
else horiZontal = false;
Encoding myAscii = Encoding.ASCII;
string thisFactory = myAscii.GetString(myImage.GetPropertyItem(271).Value).Replace("\0", "\r\n");
thisFactory += myAscii.GetString(myImage.GetPropertyItem(272).Value);
txtCameraFactory.Text = thisFactory;//changing of this text box value activate procedure to find camera picture and info
this.Text = "RangeFinder" + " - " + openFileDialog1.FileName;
}
catch (Exception) { }
}
}
uint convertToInt32U(byte[] myArray)
{
if (myArray.Length != 4)
return 0;
else
return Convert.ToUInt32(myArray[3] << 24 | myArray[2] << 16 | myArray[1] << 8 | myArray[0]);
}
private void txtCameraFactory_TextChanged(object sender, EventArgs e)
{
cameraSerach();
}
//Finding camera info and picture
private void cameraSerach()
{
txtSensorHeight.Text = "";
txtSensorWidth.Text = "";
txtSensorType.Text = "";
picCamera.Image = Properties.Resources.noPhoto;
toolTip1.SetToolTip(picCamera, "");
string camControl = "MRK";// this is for preventing finding camera names like D300 instead of D3
string camName = txtCameraFactory.Text.Replace(" ", "").Replace("-", "").ToLower() + camControl;
bool camFound = false;
byte camLoop = 0;
do
{
foreach (Camera thisCamera in allCameraInfo)
{
if (camName.Contains(thisCamera.Factory.Replace(" ", "").ToLower()) && !camFound )
{
if (camName.Contains(thisCamera.Model.Replace(" ", "").Replace("-", "").ToLower() + camControl) || (camName.Contains(thisCamera.AliasName.Replace(" ", "").Replace("-", "").ToLower() + camControl) && thisCamera.AliasName != ""))
{
txtSensorType.Text = thisCamera.SensorType;
txtSensorWidth.Text = thisCamera.SensorWidth.ToString();
txtSensorHeight.Text = thisCamera.SensorHeight.ToString();
toolTip1.SetToolTip(picCamera, thisCamera.Factory + " " + thisCamera.Model);
string picFile = Application.StartupPath + "\\Data\\" + thisCamera.Factory + "_" + thisCamera.Model.Replace(" ", "").Replace("-", "") + ".gif";
if (System.IO.File.Exists(picFile)) picCamera.Image = Image.FromFile(picFile);
camFound = true;
}
}
}
camControl = "";
camLoop++;
} while (!camFound && camLoop < 2);
}
#endregion
# region Menu Items
private void mnuExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void mnuAbout_Click(object sender, EventArgs e)
{
frmAbout myAbout = new frmAbout();
myAbout.ShowDialog();
myAbout.Dispose();
}
// select a camera manually. Especially when your file doesn�t have EXIF information
private void mnuCamera_Click(object sender, EventArgs e)
{
txtCameraFactory.Text = ((ToolStripItem)sender).OwnerItem.Text;
txtCameraFactory.Text += "\r\n" + ((ToolStripItem)sender).OwnerItem.Text + " " + ((ToolStripItem)sender).Text;
}
#endregion
#region Calculating 35 mm lens equivalent
private void txtPicFL_TextChanged(object sender, EventArgs e)
{
string myEquivalent = "";
try
{
double eq =Math.Pow ( (Math.Pow(Convert.ToSingle(txtSensorWidth.Text), 2) + Math.Pow(Convert.ToSingle(txtSensorHeight.Text), 2)),.5);
eq = Math.Round ((43.2666153/eq) * Convert.ToSingle(txtPicFL.Text ));
myEquivalent = eq.ToString();
}
catch (Exception) { }
txtPicEquivalent.Text = myEquivalent;
}
#endregion
#region Calculation of size
private void tsbFindSize_Click(object sender, EventArgs e)
{
goFindSize();
}
private void tstDistance_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter) goFindSize();
}
private void goFindSize()
{
tstSize.Text = "";
try
{
mySize = myMeasure / Convert.ToDouble(txtPicFL.Text);
mySize = myDistance * mySize;
tstSize.Text = Convert.ToString(Math.Round ( mySize / mySizeScale,2));
}
catch (Exception) { }
}
#endregion
#region Calculation of distance
private void tsbFindDistance_Click(object sender, EventArgs e)
{
goFindDistance();
}
private void tstSize_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter) goFindDistance();
}
private void goFindDistance()
{
tstDistance.Text = "";
try
{
myDistance = myMeasure / Convert.ToDouble(txtPicFL.Text);
myDistance = mySize / myDistance;
tstDistance.Text = Convert.ToString( Math.Round( myDistance / myDistanceScale,2));
}
catch (Exception) { }
}
#endregion
#region Some controls on Size
//enable or disable Size button
private void tstSize_TextChanged(object sender, EventArgs e)
{
if (tstSize.Text.Trim() == "" || tstSize.Text.Trim() == "0")
{
tsbFindDistance.Enabled = false;
tsbFindDistance.Image = Properties.Resources.right2;
}
else
{
tsbFindDistance.Enabled = true;
tsbFindDistance.Image = Properties.Resources.right;
}
// set mySize value when you type it manually
if (tstSize.Selected)
{
try
{
mySize = Convert.ToDouble(tstSize.Text) * mySizeScale;
}
catch (Exception) { }
}
}
//highligh current value
private void tstSize_Click(object sender, EventArgs e)
{
tstSize.SelectionStart = 0;
tstSize.SelectionLength = tstSize.Text.Length;
}
private void tscSizeScale_TextChanged(object sender, EventArgs e)
{
mySizeScale=exchangeSize(tscSizeScale.Text);
tstSize.Text = Convert.ToString(Math.Round(mySize / mySizeScale, 2));
}
#endregion
#region Some Controls on Distance
//enable or disable distance button
private void tstDistance_TextChanged(object sender, EventArgs e)
{
if (tstDistance.Text.Trim() == "" || tstDistance.Text.Trim() == "0")
{
tsbFindSize .Enabled = false;
tsbFindSize .Image = Properties.Resources.left2 ;
}
else
{
tsbFindSize .Enabled = true;
tsbFindSize .Image = Properties.Resources.left ;
}
// set myDistance value when you type it manually
if (tstDistance.Selected)
{
try
{
myDistance = Convert.ToDouble(tstDistance.Text) * myDistanceScale;
}
catch (Exception) { }
}
}
private void tscDistanceScale_TextChanged(object sender, EventArgs e)
{
myDistanceScale = exchangeSize(tscDistanceScale.Text);
tstDistance.Text = Convert.ToString(Math.Round(myDistance / myDistanceScale, 2));
}
//highligh current value
private void tstDistance_Click(object sender, EventArgs e)
{
tstDistance.SelectionStart = 0;
tstDistance.SelectionLength = tstDistance.Text.Length;
}
# endregion
#region metric formats
private double exchangeSize(string myScale)
{
switch (myScale.Trim().ToLower())
{
case "mm":
return .001;
case "cm":
return .01;
case "m":
return 1;
case "km":
return 1000;
case "inch":
return .0254;
case "foot":
return .3048;
case "mile":
return 1609.344;
}
return 0;
}
#endregion
#region Others
private void tsbMove_Click(object sender, EventArgs e)
{
tsbMove.Checked = true;
tsbMeasure.Checked = false;
picMain.Cursor = Cursors.Hand;
}
private void tsbMeasure_Click(object sender, EventArgs e)
{
tsbMove.Checked = false;
tsbMeasure.Checked = true;
picMain.Cursor = Cursors.Cross;
}
private void trbZoom_Scroll(object sender, EventArgs e)
{
setZoom();
}
private void setZoom()
{
myZoom = 50 / (float)trbZoom.Value;
toolTip1.SetToolTip(trbZoom ,"Zoom " + Convert.ToString((100/myZoom)) +"%");
RePaint();
}
#endregion
}
}