69304
Goto Top

VB2008 Inhalt aus gescannter PDF TIF erkennen

Hallo Leute!

Besteht die Möglichkeit, aus einem gescannten Dokument (liegt im PDF- oder TIF-Format vor) einen Bereich "einzulesen" und dann anhand diesem Bereich (falls dieser z.B. schwarz ausgemalt ist) einen Rückgabewert zu erzeugen in Form eines Bool-Wertes?


Es geht um eine Workflow-Programmierung.

User sollen auf einem Blatt Papier Kästchen "anmalen" können und über einen MFP-Kopierer in ein Verzeichnis scannen können.

Die PDF oder TIF soll dann von dem VB-Programm verarbeitet werden und dann z.B. irgendwelche SQL- oder Copy-Anweisungen ausgeführt werden.

Content-Key: 136830

Url: https://administrator.de/contentid/136830

Printed on: April 26, 2024 at 12:04 o'clock

Member: RedWraith
RedWraith Mar 04, 2010 at 12:50:58 (UTC)
Goto Top
Hi !

Ein TIF Format ist doch eine Bilddatei oder ?

Die könnte man in VB.NET einlesen und dann könnte man auf dem so erzeugten Bitmap eine Art Bilderkennung laufen lassen.

Ein Codebeispiel kann ich dir leider nicht liefern, aber das Schwierigste daran dürfte sein, die Kästchen auf dem Bild
zu "finden". Aber ich bin sicher, dass es dafür irgendwo eine Art Algorythmus gibt. Wenn du weißt, wo sich die Kästchen
befinden, musst du nurnoch prüfen, ob Sie ausgemalt sind.

Dafür müsste man eigendlich nur den Bildbereich, in dem ein Kästchen gefunden wurde, darauf überprüfen,
ob der Großteil des Bildbereichs Schwarz, bzw. Nicht-Weiß ist.

Natürlich hängt das davon ab, wie gut die eingescannte Qualität ist, ich stelle mir vor, dass bei einem reinen
S/W Scan das Ganze deutlich einfacher ist, als bei einer hochauflösenden Farbkopie.

Achja, von der PDF für ich dir abraten. PDFs sind eigendlich als Eyes-Only gedacht und lassen sich so gut wie garnicht
maschinell bearbeiten.
Mitglied: 69304
69304 Mar 04, 2010 at 13:07:21 (UTC)
Goto Top
Ein TIF Format ist doch eine Bilddatei oder ?
Jupp.

Die könnte man in VB.NET einlesen und dann könnte man auf dem so erzeugten Bitmap eine Art Bilderkennung laufen lassen.
Ja hat vielleicht jemand hier sowas?!?

Dafür müsste man eigendlich nur den Bildbereich, in dem ein Kästchen gefunden wurde, darauf überprüfen,
ob der Großteil des Bildbereichs Schwarz, bzw. Nicht-Weiß ist.

Natürlich hängt das davon ab, wie gut die eingescannte Qualität ist, ich stelle mir vor, dass bei einem reinen
S/W Scan das Ganze deutlich einfacher ist, als bei einer hochauflösenden Farbkopie.
Genau so habe ich es mir vorgestellt!
Member: RedWraith
RedWraith Mar 04, 2010 at 13:49:10 (UTC)
Goto Top
Ich werd mich mal schlau machen. Ich kenne jemanden,
der hat mit komplexeren Algorythmen direkt zu tun, mal sehen, was der sagt.

EDIT: Besagte Person ist im Urlaub. Pech.

EDIT2: Ich hab ein Tutorial gefunden, ist aber nicht ganz ohne: http://rn-wissen.de/index.php/Bildverarbeitung_Tutorial
Mitglied: 69304
69304 Mar 29, 2010 at 06:19:44 (UTC)
Goto Top
Hmm.. Danke erstmal.

Aber das Bild ist schon schwarz/weiss. Das ist nicht das Problem.


Das Problem liegt eher darin, wie ich in VB2008 das Bild in einem Programmteil "erkennen" lasse, bzw. "einlese".
Mitglied: 69304
69304 Apr 01, 2010 at 14:49:43 (UTC)
Goto Top
Ich habs face-smile

Bin eigentlich eher durch Zufall darauf gestoßen face-smile

Wenn jemand interesse hat, kann ich ihm das komplette Paket als Zip zuschicken.


Aber hier zumindest mal ein Denkanstoß, falls jmd das selbe Problem hat:

Benötigt wird:

- Form1
- Label1
- Label2
- Label3
- PictureBox1

Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices

Public Class Form1
    Private bm As Bitmap

    Protected Sub SetIndexedPixel(ByVal x As Integer, ByVal y As Integer, ByVal bmd As BitmapData, ByVal pixel As Boolean)
        Dim index As Integer = y * bmd.Stride + (x >> 3)
        Dim p As Byte = Marshal.ReadByte(bmd.Scan0, index)
        Dim mask As Byte = &H80 >> (x And &H7)
        If pixel Then
            p = p Or mask
        Else
            p = p And CByte(mask ^ &HFF)
        End If
        Marshal.WriteByte(bmd.Scan0, index, p)
    End Sub 'SetIndexedPixel  

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim X As Integer = 0
        Dim Y As Integer = 0
        Dim Schwellwert As Integer = 200
        Dim Farbe As Color
        Dim Wert1 As Integer = 0
        Dim Wert2 As Integer = 0
        Dim Wert1Check As Boolean = False
        Dim Wert2Check As Boolean = False

        Dim ofd As New OpenFileDialog
        ofd.InitialDirectory = "C:\Temp"  
        ofd.Filter = "JPG (*.jpg)|*.jpg| BMP (*.bmp)|*.bmp"  
        ofd.Title = "Wählen Sie eine Datei zum Öffnen aus"  
        If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then

            Dim img As Bitmap = CType(Image.FromFile(ofd.FileName), Bitmap)
            'Ensure that it's a 32 bit per pixel file  
            If img.PixelFormat <> PixelFormat.Format32bppPArgb Then
                Dim temp As New Bitmap(img.Width, img.Height, PixelFormat.Format32bppPArgb)
                Dim g As Graphics = Graphics.FromImage(temp)
                g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel)
                img.Dispose()
                g.Dispose()
                img = temp
            End If
            Me.PictureBox1.Image = img
            'lock the bits of the original bitmap  
            Dim bmdo As BitmapData = img.LockBits(New Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat)

            'and the new 1bpp bitmap  
            bm = New Bitmap(Me.PictureBox1.Image.Width, Me.PictureBox1.Image.Height, PixelFormat.Format1bppIndexed)
            Dim bmdn As BitmapData = bm.LockBits(New Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed)

            'scan through the pixels Y by   
            For Y = 0 To img.Height - 1
                For X = 0 To img.Width - 1
                    'generate the address of the colour pixel  
                    Dim index As Integer = Y * bmdo.Stride + X * 4

                    'check its brightness  
                    If Color.FromArgb(Marshal.ReadByte(bmdo.Scan0, index + 2), Marshal.ReadByte(bmdo.Scan0, index + 1), Marshal.ReadByte(bmdo.Scan0, index)).GetBrightness() > 0.5F Then
                        Me.SetIndexedPixel(X, Y, bmdn, True) 'set it if its bright.  
                    End If
                Next X
            Next Y

            'tidy up  
            bm.UnlockBits(bmdn)
            img.UnlockBits(bmdo)

            'display the 1bpp image  
            Me.PictureBox1.Image = bm


            For Y = 200 To 280 Step 1
                For X = 150 To 220 Step 1
                    Farbe = bm.GetPixel(X, Y)
                    If Farbe.Name = "ff000000" Then  
                        Wert1 += 1
                    End If
                Next X
            Next Y

            For Y = 300 To 360 Step 1
                For X = 150 To 220 Step 1
                    Farbe = bm.GetPixel(X, Y)
                    If Farbe.Name = "ff000000" Then  
                        Wert2 += 1
                    End If
                Next X
            Next Y

            If Wert1 > Schwellwert Then
                Wert1Check = True
            End If
            If Wert2 > Schwellwert Then
                Wert2Check = True
            End If

            Label1.Text = "Erste Box (Wert): " & Wert1 & " (" & Wert1Check & ")"  
            Label2.Text = "Zweite Box (Wert): " & Wert2 & " (" & Wert2Check & ")"  
            Label3.Text = "Schwellwert: " & Schwellwert  

        Else
            MsgBox("Abbruch")  
            Close()
            End
        End If
    End Sub
End Class