/// /// Copyright (c) 2017-2022 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; using log4net; using Common; using TBF.Rig.GenericDevices; using TBF.Resources; namespace TBF.Rig.DataEntry.StandardCamera { public partial class TestStartEndForm : Form, GenericDevices.IHasCompleted { private static readonly ILog log = LogManager.GetLogger(typeof(TestStartEndForm)); const Unit unit = Unit.m3; /// /// Static members and constructor /// static int wmNr0b; static Rotation imageRotation; static bool[] isZoomed; static Point[] zoomCenterLoc; /// static TestStartEndForm() { wmNr0b = 0; //imageRotation = new Rotation[TextBoxesCount]; isZoomed = new bool[TextBoxesCount]; zoomCenterLoc = new Point[TextBoxesCount]; } /// Arguments readonly Tst mode; /// Start, End or Deferred public readonly int WaterMetersCount; readonly IRegReader[] regReaders; readonly bool[] disabled; readonly string[] startImages; readonly string[] endImages; readonly double refVolume; readonly double warningLimLo; /// limit to display exclamation mark, typically 2x errLimLo readonly double warningLimHi; /// limit to display exclamation mark, typically 2x errLimHi readonly OcrVidi ocrVidi; readonly string ocrMessage; readonly string streamName; double denominator; /// derived from PulsesPerLtr, passed to OcrVidi string format; /// derived from PulsesPerLtr, passed to OcrVidi // To be retrieved after the form closes public double[] WMStartState; // To be retrieved after the form closes public readonly string[] WMStartStateStr; // To be retrieved after the form closes public double[] WMEndState; const int TextBoxesCount = 24; string lastImageName; int lastWmNr1; Bitmap lastImage; /// non-zoomed image Bitmap zoomedImage; Thread imageProcessingThread; /// Thread to process images public delegate void OcrTextObtainedDelegate(int ix, bool isEnd, string text); OcrTextObtainedDelegate ocrTextObtained; readonly Label[] labels; readonly TextBox[] startTextBoxes; readonly TextBox[] endTextBoxes; readonly Label[] exclamations; int[] phys2wm; /// Array: index is physical position 0..23, value is water meter position 1..X or 0 (controls hidden) int[] wm2phys; /// Array: index is water meters position 1..X (item at ix=0 is not used), value is physical position 0..23 IList enabledTextBoxes; /// Set to 'true' when the form closes public bool Completed { get { return completed; } } bool completed; /// /// Parameterless constructor initializing common part for start and endstate form /// public TestStartEndForm() { InitializeComponent(); this.Icon = Properties.Resources.TBF_icon; ControlBox = false; labels = new Label[] { label1, label2, label3, label4, label5, label6, label7, label8, label9, label10, label11, label12, label13, label14, label15, label16, label17, label18, label19, label20, label21, label22, label23, label24, }; startTextBoxes = new TextBox[] { startTextBox1, startTextBox2, startTextBox3, startTextBox4, startTextBox5, startTextBox6, startTextBox7, startTextBox8, startTextBox9, startTextBox10, startTextBox11, startTextBox12, startTextBox13, startTextBox14, startTextBox15, startTextBox16, startTextBox17, startTextBox18, startTextBox19, startTextBox20, startTextBox21, startTextBox22, startTextBox23, startTextBox24, }; endTextBoxes = new TextBox[] { endTextBox1, endTextBox2, endTextBox3, endTextBox4, endTextBox5, endTextBox6, endTextBox7, endTextBox8, endTextBox9, endTextBox10, endTextBox11, endTextBox12, endTextBox13, endTextBox14, endTextBox15, endTextBox16, endTextBox17, endTextBox18, endTextBox19, endTextBox20, endTextBox21, endTextBox22, endTextBox23, endTextBox24, }; exclamations = new Label[] { exclamation1, exclamation2, exclamation3, exclamation4, exclamation5, exclamation6, exclamation7, exclamation8, exclamation9, exclamation10, exclamation11, exclamation12, exclamation13, exclamation14, exclamation15, exclamation16, exclamation17, exclamation18, exclamation19, exclamation20, exclamation21, exclamation22, exclamation23, exclamation24, }; enabledTextBoxes = new List(); imageProcessingThread = null; completed = false; StartForceCloseHandler(); } /// /// Constructor to fill in start states /// /// Number of water meters /// Array with register reader components /// Cognex wrapper object performing OCR or null /// Array with paths to start images /// Information from CycleBeginningForm about availability of water meters public TestStartEndForm(int waterMetersCount, IRegReader[] regReaders, OcrVidi ocrVidi, string ocrMessage, string streamName, string[] startImages, bool[] disabled) : this() { mode = Tst.Start; this.regReaders = regReaders; this.WaterMetersCount = Math.Min(waterMetersCount, regReaders.Length); this.ocrVidi = ocrVidi; this.ocrMessage = ocrMessage; this.streamName = streamName; this.startImages = startImages; this.disabled = disabled; if (startImages == null || startImages.Length != WaterMetersCount) { throw new Exception("Invalid 'startImages' argument"); } this.endImages = new string[WaterMetersCount]; WMStartState = new double[WaterMetersCount]; WMStartStateStr = new string[WaterMetersCount]; ConstructorCommon(regReaders); } /// /// Constructor to fill in end states /// /// Number of water meters /// Array with register reader components /// Cognex wrapper object performing OCR or null /// Array with paths to end images /// Array with start states in default volume units (liters) /// Information entered on test start /// Information from CycleBeginningForm about availability of water meters /// Reference volume, it is used to verify the end state, show/hide exclamation if necessary /// Error limit low, it is used to verify the end state, show/hide exclamation if necessary /// Error limit high, it is used to verify the end state, show/hide exclamation if necessary public TestStartEndForm(int waterMetersCount, IRegReader[] regReaders, OcrVidi ocrVidi, string ocrMessage, string streamName, string[] startImages, double[] wmStartState, string[] wmStartStateStr, string[] endImages, bool[] disabled, double refVolume, double errLimLo, double errLimHi) : this() { mode = Tst.End; this.regReaders = regReaders; this.WaterMetersCount = Math.Min(waterMetersCount, regReaders.Length); this.ocrVidi = ocrVidi; this.ocrMessage = ocrMessage; this.streamName = streamName; this.startImages = startImages; this.WMStartState = wmStartState; this.WMStartStateStr = wmStartStateStr; this.endImages = endImages; this.disabled = disabled; this.refVolume = refVolume; this.warningLimLo = 2 * errLimLo; this.warningLimHi = 2 * errLimHi; if (startImages == null || startImages.Length != WaterMetersCount || wmStartState == null || wmStartState.Length != WaterMetersCount || wmStartStateStr == null || wmStartStateStr.Length != WaterMetersCount || endImages == null || endImages.Length != WaterMetersCount) { throw new Exception("Invalid argument(s)"); } WMEndState = new double[WaterMetersCount]; ConstructorCommon(regReaders); } /// /// Constructor for deferred evaluation, to fill in both start- and end-states /// /// Number of water meters /// Array with register reader components /// Cognex wrapper object performing OCR or null /// Array with paths to start images /// Array with paths to end images /// Information from CycleBeginningForm about availability of water meters /// Reference volume, it is used to verify the end state, show/hide exclamation if necessary /// Error limit low, it is used to verify the end state, show/hide exclamation if necessary /// Error limit high, it is used to verify the end state, show/hide exclamation if necessary public TestStartEndForm(int waterMetersCount, IRegReader[] regReaders, OcrVidi ocrVidi, string ocrMessage, string streamName, string[] startImages, string[] endImages, bool[] disabled, double refVolume, double errLimLo, double errLimHi) : this() { mode = Tst.Both; this.regReaders = regReaders; this.WaterMetersCount = Math.Min(waterMetersCount, regReaders.Length); this.ocrVidi = ocrVidi; this.ocrMessage = ocrMessage; this.streamName = streamName; this.startImages = startImages; this.endImages = endImages; this.disabled = disabled; this.refVolume = refVolume; this.warningLimLo = 2 * errLimLo; this.warningLimHi = 2 * errLimHi; if (startImages == null || startImages.Length != waterMetersCount || endImages == null || endImages.Length != waterMetersCount) { throw new Exception("Invalid argument(s)"); } WMStartState = new double[waterMetersCount]; WMStartStateStr = new string[waterMetersCount]; WMEndState = new double[waterMetersCount]; ConstructorCommon(regReaders); } void ConstructorCommon(IRegReader[] regReaders) { /// For large benches with WaterMetersCount LE 6 is TBF.Data.LineSize==1 (compound meters) int lineSize = (WaterMetersCount <= 6) ? WaterMetersCount : TBF.Data.LineSize; DeterminePhysPosWMPos(TextBoxesCount, WaterMetersCount, lineSize, out phys2wm, out wm2phys); int nrLines = (TBF.Data.WMsCount - 1) / TBF.Data.LineSize + 1; if (nrLines == 1) { Width = 1040; } } /// /// Make sure the layout of labels/text boxes on the screen /// corresponds to the layout of watermeters of the test bench. /// void DeterminePhysPosWMPos(int textBoxesCount, int waterMetersCount, int lineSize, out int[] physPos2wmPos, out int[] wmPos2PhysPos) { physPos2wmPos = new int[textBoxesCount]; /// already initialized to 0-s wmPos2PhysPos = new int[waterMetersCount + 1]; for (int i = 0; i < waterMetersCount + 1; i++) wmPos2PhysPos[i] = -1; /// initialize to -1 if (waterMetersCount < textBoxesCount) { int nrLines = waterMetersCount / lineSize; int gap = (textBoxesCount - waterMetersCount) / nrLines; int wmPos = 1; for (int ln = 0; ln < nrLines; ln++) { for (int i = 0; i < lineSize; i++, wmPos++) { physPos2wmPos[ln * lineSize + ln * gap + i] = wmPos; wmPos2PhysPos[wmPos] = ln * lineSize + ln * gap + i; } } } else { int wmPos = 1; for (int i = 0; i < textBoxesCount; i++, wmPos++) { physPos2wmPos[i] = wmPos; wmPos2PhysPos[wmPos] = i; } } } private void TestStartEndForm_Load(object sender, EventArgs e) { Localize(); for (int i = 0; i < TextBoxesCount; i++) { int wmPos = phys2wm[i]; labels[i].Visible = startTextBoxes[i].Visible = endTextBoxes[i].Visible = (wmPos > 0); if (wmPos > 0) { labels[i].Text = wmPos.ToString(); switch (mode) { case Tst.Start: if ((disabled != null && wmPos <= disabled.Length && disabled[wmPos - 1]) || (regReaders != null && wmPos <= regReaders.Length && regReaders[wmPos - 1] == null)) { startTextBoxes[i].Enabled = false; } else { startTextBoxes[i].Enabled = true; enabledTextBoxes.Add(startTextBoxes[i]); } break; case Tst.End: if ((disabled != null && wmPos <= disabled.Length && disabled[wmPos - 1]) || (regReaders != null && wmPos <= regReaders.Length && regReaders[wmPos - 1] == null)) { startTextBoxes[i].Enabled = false; endTextBoxes[i].Enabled = false; } else { startTextBoxes[i].Enabled = true; startTextBoxes[i].Text = WMStartStateStr[wmPos - 1]; endTextBoxes[i].Enabled = true; enabledTextBoxes.Add(startTextBoxes[i]); enabledTextBoxes.Add(endTextBoxes[i]); } break; case Tst.Both: if ((disabled != null && wmPos <= disabled.Length && disabled[wmPos - 1]) || (regReaders != null && wmPos <= regReaders.Length && regReaders[wmPos - 1] == null)) { startTextBoxes[i].Enabled = false; endTextBoxes[i].Enabled = false; } else { startTextBoxes[i].Enabled = true; endTextBoxes[i].Enabled = true; enabledTextBoxes.Add(startTextBoxes[i]); enabledTextBoxes.Add(endTextBoxes[i]); } break; } } } if (!string.IsNullOrEmpty(ocrMessage)) { MessageBox.Show(ocrMessage, Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } int imagesCount = ImagesToProcessCount(); log.WarnFormat("Images to process count = {0}", imagesCount); /// if (imagesCount > 0 && ocrVidi != null) { log.WarnFormat("Starting image processing thread with OcrVidi={0} and OcrStream={1}", ocrVidi, streamName); /// Delegate for a thread->form communication ocrTextObtained = new OcrTextObtainedDelegate(OnOcrTextObtained); /// Show and initalize the progress bar imageProcessingProgressLabel.Visible = true; imageProcessingProgressBar.Visible = true; imageProcessingProgressBar.Minimum = 0; imageProcessingProgressBar.Value = 0; imageProcessingProgressBar.Maximum = imagesCount; /// Start the image processing thread imageProcessingThread = new Thread(new ThreadStart(ImageProcessingThread)); imageProcessingThread.Start(); } } private void TestStartEndForm_FormClosed(object sender, FormClosedEventArgs e) { if (imageProcessingThread != null && imageProcessingThread.IsAlive) { imageProcessingThread.Join(2000); } } void Localize() { Text = (ocrVidi != null) ? string.Format("{0} ({1} / {2})", Strings.Water_Meter_States, ocrVidi, streamName) : Strings.Water_Meter_States; startLabel.Text = startLabel2.Text = string.Format("{0} [{1}]", Strings.Start, unit.ToDescription()); endLabel.Text = endLabel2.Text = string.Format("{0} [{1}]", Strings.End, unit.ToDescription()); okButton.Text = Strings.OkBtnText; } int ImagesToProcessCount() { int count = 0; /// Count the images for (int i = 0; i < WaterMetersCount; i++) { if ((mode == Tst.Start || mode == Tst.Both) && startTextBoxes[wm2phys[i + 1]].Enabled && startImages != null && startImages.Length > i && !string.IsNullOrEmpty(startImages[i])) { count++; } if ((mode == Tst.End || mode == Tst.Both) && endTextBoxes[wm2phys[i + 1]].Enabled && endImages != null && endImages.Length > i && !string.IsNullOrEmpty(endImages[i])) { count++; } } return count; } void ImageProcessingThread() { Thread.Sleep(2000); bool[] startImgProcessed = new bool[WaterMetersCount]; bool[] endImgProcessed = new bool[WaterMetersCount]; for (int attempt = 1; attempt <= 3; attempt++) { for (int i = 0; i < WaterMetersCount; i++) { double pulsesPerLtr = (regReaders != null && regReaders.Length > i && regReaders[i] != null) ? regReaders[i].PulsesPerLtr : 1; GetOcrParameters(pulsesPerLtr, out denominator, out format); if ((mode == Tst.Start || mode == Tst.Both) && startTextBoxes[wm2phys[i + 1]].Enabled && startImages != null && startImages.Length > i && !string.IsNullOrEmpty(startImages[i])) { if (!startImgProcessed[i]) { try { /// Process a start image var text = ocrVidi.Recognize(streamName, startImages[i], denominator, format); /// OCR this.Invoke(ocrTextObtained, new object[] { wm2phys[i + 1], false, text }); startImgProcessed[i] = true; } catch (Exception) { } } } if ((mode == Tst.End || mode == Tst.Both) && endTextBoxes[wm2phys[i + 1]].Enabled && endImages != null && endImages.Length > i && !string.IsNullOrEmpty(endImages[i])) { if (!endImgProcessed[i]) { try { /// Process an end image var text = ocrVidi.Recognize(streamName, endImages[i], denominator, format); /// OCR this.Invoke(ocrTextObtained, new object[] { wm2phys[i + 1], true, text }); endImgProcessed[i] = true; } catch (Exception) { } } } } } } void GetOcrParameters(double pulsesPerLtr, out double denominator, out string format) { if (pulsesPerLtr == 0.1) { denominator = 100; format = "F2"; } else if (pulsesPerLtr == 0.01) { denominator = 10; format = "F1"; } else if (pulsesPerLtr == 10) { denominator = 10000; format = "F4"; } else // if (pulsesPerLtr == 1) { denominator = 1000; format = "F3"; } } public void OnOcrTextObtained(int ix, bool isEnd, string text) { if (isEnd) { if (ix < endTextBoxes.Length && endTextBoxes[ix].Enabled) { endTextBoxes[ix].Text = text; LoadImage(null, Tst.End, ix); } } else { if (ix < startTextBoxes.Length && startTextBoxes[ix].Enabled) { startTextBoxes[ix].Text = text; LoadImage(null, Tst.Start, ix); } } imageProcessingProgressBar.Value++; } private void okButton_Click(object sender, EventArgs eArgs) { try { log.DebugFormat("okButton_Click - TextBoxesCount: [{0}], phys2wm:[{1}]", TextBoxesCount, phys2wm.ToArray().ToString()); for (int i = 0; i < TextBoxesCount; i++) { int wmPos = phys2wm[i]; if (wmPos > 0) { if (startTextBoxes[i].Enabled && startTextBoxes[i].Text != WMStartStateStr[wmPos - 1]) { double val; if (Utils.TryParseUDouble(startTextBoxes[i].Text, out val)) { WMStartState[wmPos - 1] = Units.ConvertFrom(unit, val); /// Convert to liters WMStartStateStr[wmPos - 1] = startTextBoxes[i].Text; log.DebugFormat("startTextBoxes[{0}]= {1} - wmPos= {2} - WMStartState[{3}]= {4} ", i,startTextBoxes[i].Text, wmPos, wmPos - 1,WMStartState[wmPos - 1] ); } } if (endTextBoxes[i].Enabled) { double val; if (Utils.TryParseUDouble(endTextBoxes[i].Text, out val)) { WMEndState[wmPos - 1] = Units.ConvertFrom(unit, val); /// Convert to liters log.DebugFormat("endTextBoxes[{0}]= {1} - wmPos= {2} - WMEndState[{3}]= {4} ", i,endTextBoxes[i].Text, wmPos, wmPos - 1,WMEndState[wmPos - 1] ); } } } } } catch (Exception e) { log.ErrorFormat("Exception: {0}", e.Message); return; } completed = true; Close(); } private void previousButton_Click(object sender, EventArgs e) { } private void nextButton_Click(object sender, EventArgs e) { } #region Forced close handling public void StartForceCloseHandler() { UiBridge.Bridge.CloseModelessFormHandler += delegate(object sender, EventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(OnForceClose), sender, args); } else OnForceClose(sender, args); }; } void OnForceClose(object sender, EventArgs args) { DialogResult = DialogResult.Cancel; Close(); } #endregion /// /// Calculate the approximate error and verify whether it is within limits. /// Make an exclamation mark visible if out of range. /// Similar event handler is implemented for all endTextBoxes (1..24). /// private void startTextBox1_TextChanged(object sender, EventArgs e) { UpdateExclamation(0); } private void startTextBox2_TextChanged(object sender, EventArgs e) { UpdateExclamation(1); } private void startTextBox3_TextChanged(object sender, EventArgs e) { UpdateExclamation(2); } private void startTextBox4_TextChanged(object sender, EventArgs e) { UpdateExclamation(3); } private void startTextBox5_TextChanged(object sender, EventArgs e) { UpdateExclamation(4); } private void startTextBox6_TextChanged(object sender, EventArgs e) { UpdateExclamation(5); } private void startTextBox7_TextChanged(object sender, EventArgs e) { UpdateExclamation(6); } private void startTextBox8_TextChanged(object sender, EventArgs e) { UpdateExclamation(7); } private void startTextBox9_TextChanged(object sender, EventArgs e) { UpdateExclamation(8); } private void startTextBox10_TextChanged(object sender, EventArgs e) { UpdateExclamation(9); } private void startTextBox11_TextChanged(object sender, EventArgs e) { UpdateExclamation(10); } private void startTextBox12_TextChanged(object sender, EventArgs e) { UpdateExclamation(11); } private void startTextBox13_TextChanged(object sender, EventArgs e) { UpdateExclamation(12); } private void startTextBox14_TextChanged(object sender, EventArgs e) { UpdateExclamation(13); } private void startTextBox15_TextChanged(object sender, EventArgs e) { UpdateExclamation(14); } private void startTextBox16_TextChanged(object sender, EventArgs e) { UpdateExclamation(15); } private void startTextBox17_TextChanged(object sender, EventArgs e) { UpdateExclamation(16); } private void startTextBox18_TextChanged(object sender, EventArgs e) { UpdateExclamation(17); } private void startTextBox19_TextChanged(object sender, EventArgs e) { UpdateExclamation(18); } private void startTextBox20_TextChanged(object sender, EventArgs e) { UpdateExclamation(19); } private void startTextBox21_TextChanged(object sender, EventArgs e) { UpdateExclamation(20); } private void startTextBox22_TextChanged(object sender, EventArgs e) { UpdateExclamation(21); } private void startTextBox23_TextChanged(object sender, EventArgs e) { UpdateExclamation(22); } private void startTextBox24_TextChanged(object sender, EventArgs e) { UpdateExclamation(23); } private void endTextBox1_TextChanged(object sender, EventArgs e) { UpdateExclamation(0); } private void endTextBox2_TextChanged(object sender, EventArgs e) { UpdateExclamation(1); } private void endTextBox3_TextChanged(object sender, EventArgs e) { UpdateExclamation(2); } private void endTextBox4_TextChanged(object sender, EventArgs e) { UpdateExclamation(3); } private void endTextBox5_TextChanged(object sender, EventArgs e) { UpdateExclamation(4); } private void endTextBox6_TextChanged(object sender, EventArgs e) { UpdateExclamation(5); } private void endTextBox7_TextChanged(object sender, EventArgs e) { UpdateExclamation(6); } private void endTextBox8_TextChanged(object sender, EventArgs e) { UpdateExclamation(7); } private void endTextBox9_TextChanged(object sender, EventArgs e) { UpdateExclamation(8); } private void endTextBox10_TextChanged(object sender, EventArgs e) { UpdateExclamation(9); } private void endTextBox11_TextChanged(object sender, EventArgs e) { UpdateExclamation(10); } private void endTextBox12_TextChanged(object sender, EventArgs e) { UpdateExclamation(11); } private void endTextBox13_TextChanged(object sender, EventArgs e) { UpdateExclamation(12); } private void endTextBox14_TextChanged(object sender, EventArgs e) { UpdateExclamation(13); } private void endTextBox15_TextChanged(object sender, EventArgs e) { UpdateExclamation(14); } private void endTextBox16_TextChanged(object sender, EventArgs e) { UpdateExclamation(15); } private void endTextBox17_TextChanged(object sender, EventArgs e) { UpdateExclamation(16); } private void endTextBox18_TextChanged(object sender, EventArgs e) { UpdateExclamation(17); } private void endTextBox19_TextChanged(object sender, EventArgs e) { UpdateExclamation(18); } private void endTextBox20_TextChanged(object sender, EventArgs e) { UpdateExclamation(19); } private void endTextBox21_TextChanged(object sender, EventArgs e) { UpdateExclamation(20); } private void endTextBox22_TextChanged(object sender, EventArgs e) { UpdateExclamation(21); } private void endTextBox23_TextChanged(object sender, EventArgs e) { UpdateExclamation(22); } private void endTextBox24_TextChanged(object sender, EventArgs e) { UpdateExclamation(23); } /// void UpdateExclamation(int uiCtrlPos) /// uiCtrlPos = 0 .. TextBoxesCount-1 { if ((mode == Tst.End) || (mode == Tst.Both)) { try { double startV = Utils.ParseUDouble(startTextBoxes[uiCtrlPos].Text); double startVolumeL = (unit == Unit.pulse) ? startV * regReaders[phys2wm[uiCtrlPos] - 1].LtrsPerPulse : Units.ConvertFrom(unit, startV); double endV = Utils.ParseUDouble(endTextBoxes[uiCtrlPos].Text); double endVolumeL = (unit == Unit.pulse) ? endV * regReaders[phys2wm[uiCtrlPos] - 1].LtrsPerPulse : Units.ConvertFrom(unit, endV); double err = 100.0 * (endVolumeL - startVolumeL - refVolume) / refVolume; exclamations[uiCtrlPos].Visible = (err < warningLimLo) || (warningLimHi < err); log.Debug(string.Format("DataEntry - Update unit:[{0}], startV: {1} -> {2}, endV: {3} -> {4} ", unit, startV, startVolumeL, endV, endVolumeL)); } catch { exclamations[uiCtrlPos].Visible = false; log.Debug("DataEntry - Update unit - Error uiCtrlPos: " + uiCtrlPos); } } } private void startTextBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox1); } private void startTextBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox2); } private void startTextBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox3); } private void startTextBox4_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox4); } private void startTextBox5_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox5); } private void startTextBox6_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox6); } private void startTextBox7_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox7); } private void startTextBox8_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox8); } private void startTextBox9_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox9); } private void startTextBox10_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox10); } private void startTextBox11_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox11); } private void startTextBox12_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox12); } private void startTextBox13_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox13); } private void startTextBox14_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox14); } private void startTextBox15_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox15); } private void startTextBox16_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox16); } private void startTextBox17_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox17); } private void startTextBox18_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox18); } private void startTextBox19_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox19); } private void startTextBox20_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox20); } private void startTextBox21_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox21); } private void startTextBox22_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox22); } private void startTextBox23_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox23); } private void startTextBox24_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox24); } private void endTextBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox1); } private void endTextBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox2); } private void endTextBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox3); } private void endTextBox4_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox4); } private void endTextBox5_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox5); } private void endTextBox6_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox6); } private void endTextBox7_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox7); } private void endTextBox8_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox8); } private void endTextBox9_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox9); } private void endTextBox10_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox10); } private void endTextBox11_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox11); } private void endTextBox12_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox12); } private void endTextBox13_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox13); } private void endTextBox14_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox14); } private void endTextBox15_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox15); } private void endTextBox16_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox16); } private void endTextBox17_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox17); } private void endTextBox18_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox18); } private void endTextBox19_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox19); } private void endTextBox20_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox20); } private void endTextBox21_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox21); } private void endTextBox22_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox22); } private void endTextBox23_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox23); } private void endTextBox24_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox24); } /// /// /// Process a key press within any enabled text boxe /// /// /// /// TextBox control which received the event private void ProcKeyPress(object sender, KeyPressEventArgs e, TextBox currentFocusOwner) { if (e.KeyChar == '+') { /// Process '+' key ..... Form completed okButton_Click(sender, e); } if (e.KeyChar == '\r') { /// Process key ..... Next text field if (enabledTextBoxes.Count < 2) return; /// There is just one enabled textbox for (int i = 0; i < enabledTextBoxes.Count; i++) { if (enabledTextBoxes[i] == currentFocusOwner) { /// Change focus to the next enabled text box var currentTextBox = enabledTextBoxes[(i + 1) % enabledTextBoxes.Count]; currentTextBox.Focus(); /// Load the respective image for (int j = 0; j < startTextBoxes.Length; j++) { if (startTextBoxes[j] == currentTextBox) { LoadImage(currentTextBox, Tst.Start, j); return; } } for (int j = 0; j < endTextBoxes.Length; j++) { if (endTextBoxes[j] == currentTextBox) { LoadImage(currentTextBox, Tst.End, j); return; } } /// No image found return; } } } } private void startTextBox1_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 0); } private void startTextBox2_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 1); } private void startTextBox3_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 2); } private void startTextBox4_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 3); } private void startTextBox5_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 4); } private void startTextBox6_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 5); } private void startTextBox7_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 6); } private void startTextBox8_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 7); } private void startTextBox9_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 8); } private void startTextBox10_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 9); } private void startTextBox11_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 10); } private void startTextBox12_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 11); } private void startTextBox13_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 12); } private void startTextBox14_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 13); } private void startTextBox15_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 14); } private void startTextBox16_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 15); } private void startTextBox17_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 16); } private void startTextBox18_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 17); } private void startTextBox19_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 18); } private void startTextBox20_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 19); } private void startTextBox21_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 20); } private void startTextBox22_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 21); } private void startTextBox23_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 22); } private void startTextBox24_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.Start, 23); } private void startTextBox1_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 0); } private void startTextBox2_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 1); } private void startTextBox3_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 2); } private void startTextBox4_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 3); } private void startTextBox5_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 4); } private void startTextBox6_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 5); } private void startTextBox7_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 6); } private void startTextBox8_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 7); } private void startTextBox9_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 8); } private void startTextBox10_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 9); } private void startTextBox11_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 10); } private void startTextBox12_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 11); } private void startTextBox13_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 12); } private void startTextBox14_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 13); } private void startTextBox15_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 14); } private void startTextBox16_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 15); } private void startTextBox17_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 16); } private void startTextBox18_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 17); } private void startTextBox19_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 18); } private void startTextBox20_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 19); } private void startTextBox21_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 20); } private void startTextBox22_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 21); } private void startTextBox23_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 22); } private void startTextBox24_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.Start, 23); } private void endTextBox1_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 0); } private void endTextBox2_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 1); } private void endTextBox3_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 2); } private void endTextBox4_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 3); } private void endTextBox5_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 4); } private void endTextBox6_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 5); } private void endTextBox7_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 6); } private void endTextBox8_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 7); } private void endTextBox9_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 8); } private void endTextBox10_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 9); } private void endTextBox11_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 10); } private void endTextBox12_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 11); } private void endTextBox13_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 12); } private void endTextBox14_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 13); } private void endTextBox15_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 14); } private void endTextBox16_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 15); } private void endTextBox17_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 16); } private void endTextBox18_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 17); } private void endTextBox19_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 18); } private void endTextBox20_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 19); } private void endTextBox21_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 20); } private void endTextBox22_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 21); } private void endTextBox24_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 22); } private void endTextBox23_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 23); } private void endTextBox1_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 0); } private void endTextBox2_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 1); } private void endTextBox3_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 2); } private void endTextBox4_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 3); } private void endTextBox5_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 4); } private void endTextBox6_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 5); } private void endTextBox7_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 6); } private void endTextBox8_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 7); } private void endTextBox9_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 8); } private void endTextBox10_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 9); } private void endTextBox11_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 10); } private void endTextBox12_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 11); } private void endTextBox13_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 12); } private void endTextBox14_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 13); } private void endTextBox15_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 14); } private void endTextBox16_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 15); } private void endTextBox17_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 16); } private void endTextBox18_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 17); } private void endTextBox19_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 18); } private void endTextBox20_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 19); } private void endTextBox21_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 20); } private void endTextBox22_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 21); } private void endTextBox23_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 22); } private void endTextBox24_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 23); } /// /// Loads appropriate image into pictureBox1.Image /// Handles mouse clicks and Tab-changes inside text boxes. /// /// Tst.Start or Tst.End /// 0..23 void LoadImage(object sender, Tst startOrEnd, int physPos) { int wmNr1b = phys2wm[physPos]; /// 0 means no WM if (wmNr1b <= 0) return; wmNr0b = wmNr1b - 1; string imageFileName; if (startOrEnd == Tst.Start && startImages[wmNr0b] != null) imageFileName = startImages[wmNr0b]; else if (startOrEnd == Tst.End && endImages[wmNr0b] != null) imageFileName = endImages[wmNr0b]; else imageFileName = string.Empty; if (imageFileName == lastImageName) { return; } lastImageName = imageFileName; lastWmNr1 = wmNr1b; if (string.IsNullOrEmpty(imageFileName) || !File.Exists(imageFileName)) { lastImage = null; } else { using (Bitmap tempBmp = Image.FromFile(imageFileName) as Bitmap) { Rectangle rect; if (tempBmp.Height < tempBmp.Width) { int hght = tempBmp.Height; int leftMargin = (tempBmp.Width - hght) / 2; rect = new Rectangle(leftMargin, 0, hght, hght); } else { int hght = tempBmp.Height; int wdth = tempBmp.Width; int margin = (hght - wdth) / 2; rect = new Rectangle(0, margin, wdth, wdth); } //int hght = tempBmp.Height; //int leftMargin = (tempBmp.Width - hght) / 2; //lastImage = new Bitmap(tempBmp.Clone(new Rectangle(leftMargin, 0, hght, hght), tempBmp.PixelFormat)); lastImage = new Bitmap(tempBmp.Clone(rect, tempBmp.PixelFormat)); if (isZoomed[wmNr0b]) { zoomedImage = MakeZoomedImage(lastImage, zoomCenterLoc[wmNr0b]); } } } ShowImage(); } /// /// Left click = Zoom, Right click = Unzoom /// private void pictureBox1_Click(object sender, EventArgs e) { if (lastImage == null) return; MouseEventArgs me = (MouseEventArgs)e; if (me.Button == MouseButtons.Left && !isZoomed[wmNr0b]) { switch (imageRotation) { case Rotation.R0: zoomCenterLoc[wmNr0b] = me.Location; break; case Rotation.R90: zoomCenterLoc[wmNr0b].X = pictureBox1.Size.Height - me.Location.Y - 1; zoomCenterLoc[wmNr0b].Y = me.Location.X; break; case Rotation.R180: zoomCenterLoc[wmNr0b].X = pictureBox1.Size.Width - me.Location.X - 1; zoomCenterLoc[wmNr0b].Y = pictureBox1.Size.Height - me.Location.Y - 1; break; case Rotation.R270: zoomCenterLoc[wmNr0b].X = me.Location.Y; zoomCenterLoc[wmNr0b].Y = pictureBox1.Size.Width - me.Location.X - 1; break; } zoomedImage = MakeZoomedImage(lastImage, zoomCenterLoc[wmNr0b]); isZoomed[wmNr0b] = true; ShowImage(); } else if (me.Button == MouseButtons.Right) { isZoomed[wmNr0b] = false; ShowImage(); } } private void rotateImageButton_Click(object sender, EventArgs e) { if (lastImage == null) return; if (++imageRotation == Rotation.Count) { imageRotation = Rotation.R0; } ShowImage(); } Bitmap MakeZoomedImage(Bitmap oriImage, Point centerLoc) { float picBoxW = (float)pictureBox1.Size.Width; float picBoxH = (float)pictureBox1.Size.Height; float newRelX = Math.Max(0, Math.Min(centerLoc.X / picBoxW - 0.25f, 0.5f)); float newRelY = Math.Max(0, Math.Min(centerLoc.Y / picBoxH - 0.25f, 0.5f)); Rectangle newRect = new Rectangle((int)(newRelX * oriImage.Width), (int)(newRelY * oriImage.Height), oriImage.Width / 2, oriImage.Height / 2); /// image resolution, 1280 x 960 return lastImage.Clone(newRect, oriImage.PixelFormat); } /// /// Used by ShowImage() /// Brush lightBrush = new SolidBrush(Color.LightGreen); Brush darkBrush = new SolidBrush(Color.Green); Font largeFont = new Font("arial", 24.0F, FontStyle.Bold); /// normal image Font smallFont = new Font("arial", 12.0F, FontStyle.Bold); /// zoomed image /// /// Show selected image in the picture box. /// lastWmNr1, lastImage, zoomedImage, isZoomed and imageRotation are used. /// void ShowImage() { if (lastImage == null) { pictureBox1.Image = new Bitmap(TBF.Properties.Resources.Empty); return; } Bitmap tempBmp = isZoomed[wmNr0b] ? new Bitmap(zoomedImage.Clone(new Rectangle(0, 0, zoomedImage.Width, zoomedImage.Height), zoomedImage.PixelFormat)) : new Bitmap(lastImage.Clone(new Rectangle(0, 0, lastImage.Width, lastImage.Height), lastImage.PixelFormat)); switch (imageRotation) { case Rotation.R90: tempBmp.RotateFlip(RotateFlipType.Rotate270FlipNone); break; case Rotation.R180: tempBmp.RotateFlip(RotateFlipType.Rotate180FlipNone); break; case Rotation.R270: tempBmp.RotateFlip(RotateFlipType.Rotate90FlipNone); break; } /// Write water meter number to the bitmap using (var grph = Graphics.FromImage(tempBmp)) { Font font = isZoomed[wmNr0b] ? smallFont : largeFont; int margin = isZoomed[wmNr0b] ? 1 : 2; int pixelsCount = 0; int brightness = 0; for (int x = margin; x <= 8 * margin; x += margin) { for (int y = margin; y <= 8 * margin; y += margin) { brightness += (int)tempBmp.GetPixel(x, y).G; pixelsCount++; } } brightness /= pixelsCount; Brush brush = (brightness > 160) ? darkBrush : lightBrush; grph.DrawString(lastWmNr1.ToString(), font, brush, margin, margin); } pictureBox1.Image = tempBmp; } } }