对于我的应用程序,我需要“检测”发票上的条形码。为此,我在条形码的第一个出现位置周围绘制了一个矩形,然后在第一次与第二个出现位置之间绘制了一个矩形,以将其高度保存为条形码之间的距离,最后,我让C#围绕该条形码生成了其他矩形。剩余的条形码,使用第一个矩形作为模板,第二个作为条形码之间的距离的度量。我的问题是C#生成的矩形与我之前定义的矩形不一致。
在假设不一致是线性增加的前提下,我尝试使用Y = AX + B抵消不一致,但这仅适用于一张特定的发票,当我尝试另一张发票时,它仍然不一致。
首先,我使用鼠标事件来绘制矩形。我将此代码用于我自己绘制的所有矩形:
private void PbPreview_MouseDown(object sender, MouseEventArgs e)
{
/*
When the left mouse button is pressed, the mouseown bool will be set to true, which enables to program to start drawing the rectangle. The current location of the cursor is saved in the XY variable.
*/
IsMouseDown = true;
XY = e.Location;
}
private void PbPreview_MouseUp(object sender, MouseEventArgs e)
{
/*
When the mouse is released, the current location of the cursor is saved in a seperate variable (X1Y1). These two variables will be used to draw the actual rectangle.
*/
if (IsMouseDown)
{
X1Y2 = e.Location;
IsMouseDown = false;
First = false;
if (Updated)
{
//MessageBox.Show("Ding is bijgewerkt");
Updated = false;
}
}
if (Rect != null)
{
try
{
bool AfstandGemeten;
Bitmap SRC = new Bitmap(PbPreview.Image, PbPreview.Width, PbPreview.Height);
/*
The GaanWeAfstandMeten bool determines if you are drawing the first or second rectangle. If the second rectangle has been drawn, the AfstandGemeten Bool will be set to true, enabeling the program to start generating the remaining rectangles.
*/
if (!GaanWeAfstandMeten)
{
AfstandGemeten = false;
GaanWeAfstandMeten = true;
}
else
{
AfstandGemeten = true;
GaanWeAfstandMeten = false;
}
/*
When all required items have been marked and the distance has been defined, the function to generate the remaining rectangles is called.
*/
if (Index == CheckedOnderdelen().Count && AfstandGemeten)
{
GetProducten(Afstand);
}
}
catch(Exception E)
{
MessageBox.Show("Er is een fout opgetreden bij het bijsnijden van de afbeelding." + E.Message);
}
}
}
private void PbPreview_MouseMove(object sender, MouseEventArgs e)
{
/*
When the user moves the cursor while the left mouse button is pressed, the current location of the cursor is saved in X1Y1. The XY and X1Y1 variables are used to draw te rectangle.
*/
if (IsMouseDown)
{
X1Y2 = e.Location;
Refresh();
}
}
private void PbPreview_Paint(object sender, PaintEventArgs e)
{
/*
In case the rectangle is initialised, the function to draw the rectangle is called. The color of the rectangle will differ depending on wether it is the first, second or debug rectangle.
*/
if(Rect != null)
{
if (!GaanWeAfstandMeten)
{
e.Graphics.DrawRectangle(Pens.Red, GetRect());
First = true;
DebugLabel.Text = BackupRect.Size.ToString();
}
else if (Fixing)
{
e.Graphics.DrawRectangle(Pens.Coral, GetRect());
}
else
{
e.Graphics.DrawRectangle(Pens.Blue, GetRect());
Afstand = Rect.Height;
DebugLabel.Text = Afstand.ToString();
}
}
}
第二,下面是绘制矩形的函数:
public Rectangle GetRect()
/*
Function to define the rectangle.
*/
{
Rect = new Rectangle();
Rect.X = Math.Min(XY.X, X1Y2.X);
Rect.Y = Math.Min(XY.Y, X1Y2.Y);
Rect.Width = Math.Abs(XY.X - X1Y2.X);
Rect.Height = Math.Abs(XY.Y - X1Y2.Y);
/*
In case it's the first rectangle that is being drawn, its properties are being saved in a backup rectangle to make sure it won't be overwritten when the second rectangle is drawn.
*/
if (First)
{
BackupRect = new Rectangle();
//BackupRect = Rect;
BackupRect.X = Rect.X;
BackupRect.Y = Rect.Y;
BackupRect.Width = Rect.Width;
BackupRect.Height = Rect.Height;
Updated = true;
}
/*
Same deal as above
*/
if (Fixing)
{
FixtRect = new Rectangle();
FixtRect.X = Rect.X;
FixtRect.Y = Rect.Y;
FixtRect.Width = Rect.Width;
FixtRect.Height = Rect.Height;
}
return Rect;
}
最后,用于生成其余矩形的函数:
public List<Bitmap> GetProducten(int ItemAfstand)
{
List<Bitmap> Output = new List<Bitmap>();
foreach (Bitmap B in Set)
{
int LocationX = Rect.X;
int LocationY = Rect.Y;
Bitmap Next = new Bitmap(Rect.Width, Rect.Height);
Graphics G = Graphics.FromImage(WorkImage[PreviewIndex]);
Graphics J = Graphics.FromImage(Next);
bool Finished = false;
BackupRect.Height += 10;
ItemAfstand += 30;
GaanWeAfstandMeten = true;
pen = new Pen(Color.Red);
BackupRect.Height = Convert.ToInt32(BackupRect.Height * 2.4);
BackupRect.Y = Convert.ToInt32(LocationY * 2.3);
// Iterating through the file until there are no barcodes left.
while (!Finished)
{
if (BackupRect.Y <= WorkImage[PreviewIndex].Height)
{
if (!Fixing)
{
//Output.Add(Next);
/*
Ensuring the rectangle that is generated has the same starting point as the drawn rectangle.
*/
Rect.X = LocationX;
Rect.Y = LocationY;
//Drawing the rectangle around the barcode.
pen = new Pen(Color.Green);
G.DrawRectangle(pen, BackupRect);
PbPreview.Image = WorkImage[PreviewIndex];
BackupRect.Y += Convert.ToInt32(ItemAfstand * 2.3); //Increasing the distance to make the next rectangle go to the next barcode.
}
else
{
//For debugging. Can be ignored
BackupRect.Y = 500000;
//G.DrawRectangle(Pens.Green, FixtRect.Y, FixtRect.X, FixtRect.Width, FixtRect.Height);
}
}
else //Break the loop when the entire invoice has been processed.
{
Finished = true;
MessageBox.Show("Finished");
if (MessageBox.Show("Zijn alle barcodes correct geselecteerd?", "Waarschuwing", MessageBoxButtons.YesNo) == DialogResult.No)
{
MessageBox.Show("Select the remaining barcodes using the debug rectangle.");
Fixing = true;
//pen = new Pen(Color.Pink);
}
else
{
MessageBox.Show("Save the barcodes");
}
}
}
}
return Output;
}
如前所述,我首先绘制一个矩形,然后再画一个矩形以定义两个条形码之间的距离。然后,使用这些数据,程序将生成其余的矩形。但是,这些矩形根本不会出现在应有的位置。当涉及图像和矩形时,“像素”似乎有所不同。 [出于未知的原因,stackoverflow不允许我粘贴屏幕截图。如果有人可以为我提供解决方案,我很乐意添加我的屏幕截图]
非常感谢! 〜梅尔文