Hallo liebes Forum,
da ich Nachhilfe gebe, scanne ich oft ein DIN A4 Blatt ein. Dieses schneide ich mit Picasa zurecht (siehe Anhang). Ich möchte nun, dass ein Programm das macht. Daher muss ich die Schrift erkennen. Ich habe festgestellt, dass im Bild des Scanners einige Fehlpixel enthalten sind (sie sind dunkel statt weiß) trotz .PNG von vornherein.
Dann habe ich mir gedacht, fang ich doch ganz grob an, und erkenne erstmal ein schwarzes Rechteck. Das klappte mittelmäßig. Aufgrund der Fehlpixel / Pixelfehler wird das umrandete Rechteck nach rechts und unten etwas zu groß. Da kam mir die Idee, dass ich checken muss, ob die letzten 5 Pixel dunkel waren! Und siehe da, gelöst! Aber nun mein Problem, denn es geht ja um die Schrift. Die Schrift ist so dünn, dass ich nicht (immer) fragen kann "Habe ich 5 dunkle Pixel gesehen?".
Das nächste Ziel ist dann, wie oben genannt, das erkannte Rechteck mit der Schrift darin zu cutten und als einzelnes Bild zu speichern.
Wie würdet ihr das angehen?
PS:
da ich Nachhilfe gebe, scanne ich oft ein DIN A4 Blatt ein. Dieses schneide ich mit Picasa zurecht (siehe Anhang). Ich möchte nun, dass ein Programm das macht. Daher muss ich die Schrift erkennen. Ich habe festgestellt, dass im Bild des Scanners einige Fehlpixel enthalten sind (sie sind dunkel statt weiß) trotz .PNG von vornherein.
Dann habe ich mir gedacht, fang ich doch ganz grob an, und erkenne erstmal ein schwarzes Rechteck. Das klappte mittelmäßig. Aufgrund der Fehlpixel / Pixelfehler wird das umrandete Rechteck nach rechts und unten etwas zu groß. Da kam mir die Idee, dass ich checken muss, ob die letzten 5 Pixel dunkel waren! Und siehe da, gelöst! Aber nun mein Problem, denn es geht ja um die Schrift. Die Schrift ist so dünn, dass ich nicht (immer) fragen kann "Habe ich 5 dunkle Pixel gesehen?".
Das nächste Ziel ist dann, wie oben genannt, das erkannte Rechteck mit der Schrift darin zu cutten und als einzelnes Bild zu speichern.
Wie würdet ihr das angehen?
PS:
Option Strict On
habe ich in den Projekteigenschaften gesetzt.VB.NET-Quellcode
- Imports Microsoft.WindowsAPICodePack.Dialogs
- Public NotInheritable Class Form1
- Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
- Me.BackColor = Color.FromArgb(163, 226, 255)
- Button1.BackColor = Color.FromArgb(207, 240, 255)
- NumericUpDown1.Value = 2
- End Sub
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- TextBox_Xmin.Text = ""
- TextBox_Xmax.Text = ""
- TextBox_Ymin.Text = ""
- TextBox_Ymax.Text = ""
- Application.DoEvents()
- Dim Pfad As String = ""
- Using OFD As New CommonOpenFileDialog
- OFD.Title = "Bild auswählen, das beschnitten werden soll"
- OFD.Filters.Add(New CommonFileDialogFilter("JPEG", ".jpg"))
- OFD.Filters.Add(New CommonFileDialogFilter("Bitmap", ".bmp"))
- OFD.Filters.Add(New CommonFileDialogFilter("PNG", ".png"))
- OFD.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
- OFD.IsFolderPicker = False
- If OFD.ShowDialog() = DialogResult.OK Then
- Pfad = System.IO.Path.GetFullPath(OFD.FileName)
- Else
- Exit Sub
- End If
- End Using
- Using Image As New Bitmap(Pfad)
- Dim White As Color = Color.FromArgb(255, 255, 255)
- Dim Black As Color = Color.FromArgb(0, 0, 0)
- Dim akt_Color As Color
- Dim tolerance As Int16 = CShort(NumericUpDown1.Value)
- Dim Red_min, Red_max As Int16
- Dim Green_min, Green_max As Int16
- Dim Blue_min, Blue_max As Int16
- Red_min = CShort(Math.Max(Black.R - tolerance, 0))
- Red_max = CShort(Math.Min(Black.R + tolerance, 255))
- Green_min = CShort(Math.Max(Black.G - tolerance, 0))
- Green_max = CShort(Math.Min(Black.G + tolerance, 255))
- Blue_min = CShort(Math.Max(Black.B - tolerance, 0))
- Blue_max = CShort(Math.Min(Black.B + tolerance, 255))
- Dim Cnt As Int32 = 0
- Dim XMIN As Int16 = CShort(0)
- Dim YMIN As Int16 = CShort(0)
- Dim XMAX As Int16 = CShort(0)
- Dim YMAX As Int16 = CShort(0)
- For X As Int16 = 0 To CShort(Image.Size.Width - 1) Step 1
- For Y As Int16 = 0 To CShort(Image.Size.Height - 1) Step 1
- akt_Color = Image.GetPixel(X, Y)
- If (akt_Color.R >= Red_min AndAlso akt_Color.R <= Red_max) AndAlso
- (akt_Color.G >= Green_min AndAlso akt_Color.G <= Green_max) AndAlso
- (akt_Color.B >= Blue_min AndAlso akt_Color.B <= Blue_max) Then
- If Cnt = 0 Then 'Allererste Werte
- XMIN = X
- TextBox_Xmin.Text = XMIN.ToString
- YMIN = Y
- TextBox_Ymin.Text = YMIN.ToString
- Application.DoEvents()
- End If
- Cnt += 1
- If X > XMAX Then 'Allerhöchste Werte
- XMAX = X
- TextBox_Xmax.Text = XMAX.ToString
- Application.DoEvents()
- End If
- If Y > YMAX Then
- YMAX = Y
- TextBox_Ymax.Text = YMAX.ToString
- Application.DoEvents()
- End If
- End If
- Next
- Next
- Using g_img As Graphics = Graphics.FromImage(Image)
- g_img.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy
- Using Pen1 = New Pen(Color.FromArgb(191, 191, 0), CSng(3.0F))
- Dim myRect As New Rectangle(XMIN, YMIN, XMAX, YMAX)
- g_img.DrawRectangle(Pen1, myRect)
- Dim Substr As String = Pfad.Substring(0, Pfad.LastIndexOf("\") + 1)
- Dim Bildname As String = Pfad.Substring(Pfad.LastIndexOf("\") + 1, Pfad.LastIndexOf(".") - (Pfad.LastIndexOf("\") + 1))
- Image.Save(Substr & Bildname & " - Kopie.png", System.Drawing.Imaging.ImageFormat.Png)
- End Using
- End Using
- End Using
- GC.Collect()
- End Sub
- End Class
An die Neulinge: Nutzt
Option Strict On
und Option Infer Off
. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.