Bildbearbeitung bzw. Bildausschnitt

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von lris08.

    Bildbearbeitung bzw. Bildausschnitt

    Hallo,

    ich bin gerade am überlegen eine kleine Programmerweiterung für meine Adressdatenbank zu machen.

    Habe bei einigen meiner Kontakte auch ein Bild hinterlegt. Nun ist es aber so, dass man oft die Bilder erst mal in einem Bildbearbeitungsprogramm bearbeiten muß, ausschneiden (also nur das Gesicht)... und das geht mir immer bisserl auf den Wecker :)


    Bin nun am überlegen ein Form zu machen mit einer relativ großen PicBox, so 800 x 600. wenn da ein bild reingeladen wird, soll eine ein art Raser erscheinen, wie ein mega große Lupe nur rechteckig wo ich den Bereich des hochgeladenen Bildes ausschneiden kann.
    So was hat auch ebay :) ... lädt man da ein bild hoch, kann ich den Bereich eingrenzen... so was hätte ich gerne..

    Hat da vielleicht einer eine Idee dazu ? :)

    Hab nicht einen hauch an Idee wie ich das realisieren könnte... aber hilfreich wäre das alle mal :) oder ?

    Gruß lris
    Nun du lädst ein Bild in die PB. Darein zeichnest du via GDI einen Auswahlrahmen wenn mit der Maus in das Bild geklickt wird. Ich würde keine Feste größe nehmen sondern eher das Verhältnis bestimmt. Also Breite = Höhe z.B. so kann der Benutzer aus dem Bild einen 50px x 50px Ausschnis auswählen, welcher dann jeadoch auf 100px x 100px vergrößert wird, welches die Endmaße des Bildes sind. Ebenso kann der User einen 200px x 200px Bereich von dem Bild auswählen, dann würde das bild eben verkleinert. Das ist alles mit GDI möglich und auch nicht groß kompliziert. Denke das komplizierteste daran wäre die auswahlbox für den Bildausschnitt zu machen.
    Hmm... ok, also jetzt werd ich da richtig neugierig :) ich werde mich mal die nächsten Tage da weiter damit beschäftigen :)


    mal eine Frage zum herkömmlichen Laden eines Bildes...

    Kann es sein, dass bei unten genannten Code eine Verbindung zum Bild offen bleibt?
    Wenn ich mit diesem Code ein Bild in eine PicturBox lade, dass Programm noch läuft kann ich das Bild nicht löschen. Beende ich das Programm, kann ich das Bild auch auf der Festplatte löschen...

    VB.NET-Quellcode

    1. Private Sub Bild_DIMS_laden(ByVal PicNR As String)
    2. Dim BildAlsDateiPfad As String = Form1.Archiv_Pfad & _
    3. "\FILES_" & Form1.Archiv_Name & "\FILES\Pers_SECRET\" & PicNR & ".jpg"
    4. If File.Exists(BildAlsDateiPfad) Then
    5. Me.pb1.Image = New System.Drawing.Bitmap(BildAlsDateiPfad)
    6. Else
    7. Me.pb1.Image = My.Resources.fehllt
    8. End If
    9. End Sub
    Hi
    Machs doch im MouseDown-, MouseMove- und MouseUp-Event. Dort kannst du den oberen linken und den unteren rechten Punkt wählen. Wenn du dann ein fixes Seitenverhältnis wählst, hast du die richtigen Bildmaße. Du musst dann das Seitenverhältnis nur noch so anpassen, dass der kleinere/größere der Vielfachen des Seitenverhältnisses genommen wird, um die größe des Rasters zu bestimmen. Per Refresh kannst du dann auch noch ein Rechteck darauf zeichnen, das den ausgewählten Bereich bestimmt (im Paint-Event).
    Anschließend erzeugst du eine Bitmap. Dem Konstruktor kannst du die Breite und Höhe übergeben und mit Graphics.FromGraphics kannst du dann auf die Bitmap zeichnen. Also zeichnest du nur noch das Bild per DrawImage, indem du das Zielrechteck so festlegst, dass die Punkte auf der PictureBox eben die Eckpunkte der gezeichneten Bitmap sind. Anschließend rufst du für das erzeugte Graphics-Objekt noch Dispose auf (oder benutzt gleich Using). Die Bitmap kannst du dann der PictureBox zuweisen.

    Zwar 2 Beiträge zu spät, aber naja.

    Gruß
    ~blaze~
    so ... ich hab mich da mal umgeschaut... is nicht so ganz einfach das wirklich zu verstehen...

    bei diesem code wird ein bild in PB1 geladen, wenn ich es mit einem "gummiband" markiere, sollte er eigentlich nur den markierten bereich in PB2 kopieren.

    beim kopiervorgang macht er jedoch was falsch... schaut euch mal das anhängende Bild an... steig nicht dahinter warum er das bild so komisch zuschneidet...

    Könnt Ihr mir sagen was der da macht ???


    VB.NET-Quellcode

    1. Public Class Form1
    2. Private PFile As String
    3. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    4. PFile = "C:\Users\<USER>\Pictures\Neuer Ordner (2)\19072010008.jpg"
    5. Me.PictureBox1.Image = Image.FromFile(PFile)
    6. End Sub
    7. Dim rubbervisible As Boolean = False
    8. Dim rubbercancel As Boolean = False
    9. Dim rubberpos As Point
    10. Dim rubbersize As Size
    11. Dim rubberpos_orig As Point
    12. Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    13. rubbercancel = False
    14. rubberpos_orig = New Point(e.X, e.Y)
    15. rubberpos = PictureBox1.PointToScreen(rubberpos_orig)
    16. rubbersize = New Size(0, 0)
    17. ' Startrechteck zeichnen
    18. DrawRubberBox()
    19. End Sub
    20. Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    21. If e.Button <> MouseButtons.None And rubbercancel = False Then
    22. Dim x As Integer = e.X
    23. Dim y As Integer = e.Y
    24. If x < 0 Then x = 0
    25. If x > PictureBox1.ClientSize.Width Then x = PictureBox1.ClientSize.Width
    26. If y < 0 Then y = 0
    27. If y > PictureBox1.ClientSize.Height Then y = PictureBox1.ClientSize.Height
    28. ' bisheriges Rechteck löschen
    29. RemoveRubberBox()
    30. ' neues Rechteck zeichnen
    31. rubbersize = New Size(x - rubberpos_orig.X, y - rubberpos_orig.Y)
    32. Text = x.ToString() '& y.ToString & rubbersize.ToString()
    33. DrawRubberBox()
    34. End If
    35. End Sub
    36. Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    37. If rubbercancel Then Exit Sub
    38. ' Rechteck löschen
    39. RemoveRubberBox()
    40. ' als Ergebnis Rechteck zeichnen
    41. Dim x0, y0, x1, y1, tmp As Integer
    42. Dim gr As Graphics = Graphics.FromHwnd(PictureBox1.Handle)
    43. Dim img As Image
    44. Dim buffer As Bitmap
    45. img = PictureBox1.Image
    46. ' Rechteck von (x0,y0) nach (x1,y1)
    47. x0 = rubberpos_orig.X
    48. x1 = x0 + rubbersize.Width
    49. If x0 > x1 Then tmp = x0 : x0 = x1 : x1 = tmp
    50. y0 = rubberpos_orig.Y
    51. y1 = y0 + rubbersize.Height
    52. If y0 > y1 Then tmp = y0 : y0 = y1 : y1 = tmp
    53. 'buffer = CropBitmap(CType(img, Bitmap), x0, y0, x1, CInt(CLng(y1 * 1.2)))
    54. buffer = CropBitmap(CType(img, Bitmap), x0, y0, x1, y1)
    55. PictureBox2.Image = buffer
    56. PictureBox2.SizeMode = PictureBoxSizeMode.Zoom
    57. buffer = Nothing 'verhindert OutOfMemory Exception
    58. gr.Dispose()
    59. 'buffer.Dispose())'Exception wird ausgelöst
    60. End Sub
    61. Private Sub Form1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Leave
    62. RemoveRubberBox()
    63. rubbercancel = True
    64. End Sub
    65. Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
    66. RemoveRubberBox()
    67. rubbercancel = True
    68. End Sub
    69. Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles MyBase.FormClosing
    70. 'MessageBox.Show("Hallo")
    71. End Sub
    72. Private Sub DrawRubberBox()
    73. rubbervisible = True
    74. ControlPaint.DrawReversibleFrame( _
    75. New Rectangle(rubberpos, rubbersize), _
    76. Color.White, FrameStyle.Dashed)
    77. End Sub
    78. Private Sub RemoveRubberBox()
    79. If rubbervisible = True Then
    80. ControlPaint.DrawReversibleFrame( _
    81. New Rectangle(rubberpos, rubbersize), _
    82. Color.White, FrameStyle.Dashed)
    83. End If
    84. rubbervisible = False
    85. End Sub
    86. Private Function CropBitmap(ByRef bmp As Bitmap, ByVal cropX As Integer, ByVal cropY As Integer, ByVal cropWidth As Integer, ByVal cropHeight As Integer) As Bitmap
    87. Dim rect As New Rectangle(cropX, cropY, cropWidth, cropHeight)
    88. Dim cropped As Bitmap = bmp.Clone(rect, bmp.PixelFormat)
    89. Return cropped
    90. End Function
    91. End Class
    Bilder
    • Image3.jpg

      103,72 kB, 1.007×455, 286 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „lris08“ ()

    Habe meinen oberen Beitrag geändert...

    bei der alten Version, die ich ausprobiert habe... Gibt er mir folgenden Fehler aus:
    Fehler beim Auflösen der Überladung. Keine zugreifbare Chars akzeptiert diese Anzahl von Argumenten.

    und dies bei folgender Codezeile:

    VB.NET-Quellcode

    1. Dim Img2 As Bitmap = PFile.Clone(Ausschnitt, Imaging.PixelFormat.DontCare)



    der gesamte alte Code nochmal:

    VB.NET-Quellcode

    1. Private startPt, endpt As Point
    2. Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    3. startPt = Nothing
    4. endpt = Nothing
    5. If e.Button = Windows.Forms.MouseButtons.Left Then
    6. startPt = PictureBox1.PointToScreen(e.Location)
    7. End If
    8. End Sub
    9. Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    10. If e.Button = Windows.Forms.MouseButtons.Left Then
    11. If endpt = Nothing Then
    12. endpt = PictureBox1.PointToScreen(e.Location)
    13. End If
    14. ControlPaint.DrawReversibleFrame(New Rectangle(startPt.X, startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y), _
    15. Color.Orange, FrameStyle.Dashed)
    16. endpt = PictureBox1.PointToScreen(e.Location)
    17. ControlPaint.DrawReversibleFrame(New Rectangle(startPt.X, startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y), _
    18. Color.Orange, FrameStyle.Dashed)
    19. End If
    20. End Sub
    21. Private Sub PictureBox2_MouseMove(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox2.MouseMove
    22. Dim Ausschnitt As New Rectangle(startPt.X, startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y)
    23. Dim Img2 As Bitmap = PFile.Clone(Ausschnitt, Imaging.PixelFormat.DontCare)
    24. Me.PictureBox2.Image = New System.Drawing.Bitmap(Img2)
    25. End Sub
    Ich würde das wirklich mit GDI machen. Da kannst du das Bild auch an die Größe der PictureBox anpassen. Der Fehler dürfte eigentlich nicht auftreten, wenn PFile eine Bitmap, kein Image, ist. Bitmap.FromFile usw. laden übrigens ebenfalls Image-Objekte. Die Methode wird von Image geerbt.

    Ganz vergessen: Was hat das Chars da zu bedeuten?

    Gruß
    ~blaze~
    so nun habe ich mich wieder dem ursprünglichen Code zugewandt.

    Bisher funktioniert das schon mal sehr gut alles, bis auf die Tatsache, dass der markierte Bereich noch nicht korrekt übernommen werd.

    Ich denke mal es hat was mit dem x und y koordinaten zu tun.

    anbei ein bild, linkes bild original mit markierung - rechtes bild sollte eigentlich was anderes dargestellt werden... hoffe man kann es bisserl erkennen...

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. PictureBox1.Image = Image.FromFile("DasBildAlsGanzerPfad")
    4. End Sub
    5. Private startPt, endpt As Point
    6. Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As _
    7. System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    8. startPt = Nothing
    9. endpt = Nothing
    10. If e.Button = Windows.Forms.MouseButtons.Left Then
    11. startPt = PictureBox1.PointToScreen(e.Location)
    12. End If
    13. End Sub
    14. Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As _
    15. System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    16. If e.Button = Windows.Forms.MouseButtons.Left Then
    17. If endpt = Nothing Then
    18. endpt = PictureBox1.PointToScreen(e.Location)
    19. End If
    20. ControlPaint.DrawReversibleFrame(New Rectangle(startPt.X, _
    21. startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y), _
    22. Color.Orange, FrameStyle.Dashed)
    23. endpt = PictureBox1.PointToScreen(e.Location)
    24. ControlPaint.DrawReversibleFrame(New Rectangle(startPt.X, _
    25. startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y), _
    26. Color.Orange, FrameStyle.Dashed)
    27. End If
    28. tbar_xy.Text = "XY: " & startPt.X & " " & startPt.Y & " " & endpt.X - startPt.X & " " & endpt.Y - startPt.Y
    29. End Sub
    30. Private Sub PictureBox2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox2.MouseMove
    31. If PictureBox1.Image Is Nothing Then
    32. MessageBox.Show("Kein Bild vorhanden...")
    33. Return
    34. End If
    35. Dim img As Bitmap = New Bitmap(PictureBox1.Image)
    36. Dim section As Rectangle = New Rectangle(startPt.X, startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y)
    37. PictureBox2.Image = CropImage(img, section)
    38. 'img = CropImage(img, section)
    39. 'img.Save("")
    40. End Sub
    41. Function CropImage(ByVal source As Bitmap, ByVal section As Rectangle) As Bitmap
    42. Dim bmp As New Bitmap(section.Width, section.Height)
    43. Dim g As Graphics = Graphics.FromImage(bmp)
    44. g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel)
    45. Return bmp
    46. End Function
    47. End Class


    ich denke diese Zeile

    Quellcode

    1. Dim section As Rectangle = New Rectangle(startPt.X, startPt.Y, endpt.X - startPt.X, endpt.Y - startPt.Y)

    stimmt nicht so richtig.

    Irgendwie steige ich da nicht dahinter... Könnt's ma da mal bisserl unter die arme greifen ?

    lris
    Bilder
    • Image3.jpg

      82,69 kB, 774×547, 216 mal angesehen
    hey, versuch mal den code. ist etwas einfacher^^


    VB.NET-Quellcode

    1. Public SelectionRec As New Rectangle
    2. Public _MouseDown As Boolean = False
    3. Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    4. _MouseDown = True
    5. With SelectionRec
    6. .X = e.X
    7. .Y = e.Y
    8. End With
    9. End Sub
    10. Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    11. If _MouseDown = True Then
    12. With SelectionRec
    13. .Width = e.X - .X
    14. .Height = e.Y - .Y
    15. End With
    16. PictureBox1.Invalidate()
    17. End If
    18. End Sub
    19. Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    20. _MouseDown = False
    21. With SelectionRec
    22. .Width = e.X - .X
    23. .Height = e.Y - .Y
    24. End With
    25. PictureBox1.Invalidate()
    26. PictureBox2.Image = CropImage(New Bitmap(PictureBox1.Image), SelectionRec)
    27. End Sub
    28. Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
    29. With e.Graphics
    30. .DrawRectangle(Pens.Red, SelectionRec)
    31. End With
    32. End Sub
    33. Function CropImage(ByVal source As Bitmap, ByVal section As Rectangle) As Bitmap
    34. Dim bmp As New Bitmap(section.Width, section.Height)
    35. Dim g As Graphics = Graphics.FromImage(bmp)
    36. g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel)
    37. Return bmp
    38. End Function



    PS: wenn du den bereich von unten rechts nach oben links auswähls kommt einfehler. das musst du vllt nohc ausbessern