none
bitmap und PictureBox.image RRS feed

  • Frage

  • Hallo ,

    bin seit kurzem von Vb6 zu Windows express 2010 VB.Net umgestiegen und habe so meine Schwierigkeiten . Es gelingt mir nicht ein Bild in das Image einer PictureBox zu zeichnen . Wenn ich das Image weitergebe ist immer nur das ursprüngliche Image , ohne die eingefügte Grafik vorhanden . Was muss ich machen ,um eine Bitmap mit der neu eingefügten Grafik zu bekommen ? Als Beispiel ein kleines Programm : 2 PictureBoxen mit 2 identischen Bildern , in die erste wird ein roter Rahmen gezeichnet , das image in eine Bitmap geladen , diese Bitmap in das Image von Bild 2 geladen >> Ergebnis : ein Bild ohne Rahmen .

    ImportsSystem.Drawing

    PublicClassForm1

    Publicbmp AsBitmap

    Publicladefile AsString

    PrivateSubForm1_Load(sender AsSystem.Object, e AsSystem.EventArgs) HandlesMyBase.Load

    ladefile = "C:\Aepfel.JPG"

    bmp = NewBitmap(ladefile)

    PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage

    PictureBox1.Image = bmp

    Invalidate()

    EndSub

    PrivateSubPictureBox1_Paint(sender AsObject, e AsSystem.Windows.Forms.PaintEventArgs) HandlesPictureBox1.Paint

    Dimg AsGraphics= e.Graphics

    g.DrawRectangle(Pens.Red, 20, 20, 100, 100)

    bmp = CType(PictureBox1.Image, Bitmap)

    PictureBox2.SizeMode = PictureBoxSizeMode.StretchImage

    PictureBox2.Image = bmp

    EndSub

    EndClass

    Freitag, 15. Februar 2013 07:23

Alle Antworten

  • Hallo ,

     offensichtlich ist meine Frage  unverständlich gestellt , weil keine Antwort kommt . in VB6 war das mit PaintPicture doch ein einziger Befehl mit Ziel und Ursprungsgrafik . Mit GDI+ sollte es doch genauso einfach sein . Ich habe schon weiter versucht , bin aber so nicht zufrieden , da die neue Image nur aus der Grafik und dem image zusammengesetzt ist . Ich möchte aber nur ein Image bestehend aus dem Image und der Zeichnung , so daß ich nicht 2 mal speichern muß .

    Ich muß hier z.B.  PictureBox1.Image.Save("C:\Apfel.bmp") u.

    PictureBox2.Image.Save("C:\Zeichnung.bmp") speichern

    Ich möchte aber PictureBox3.Image.Save("C:\Zeichnung_mitImage.bmp") speichern

    Meine Picturebox hat als Image nur "Apfel.bmp"

    Meine schlechte Lösung :

    3Buttons , 3 PictureBoxen

    Die Buttons der Reihe nach betätigen .

    Picturebox1 mit Image bmp geladen .

    In Picturebox2 bit als Image (Elipse + Rechteck )

    in Picturebox3 Image = bmp + Graphic =bit

    Imports System.Drawing
    Public Class Form1
        Public bmp As Bitmap
        Public bit As Bitmap
        Public ladefile As String
        Public Button As Integer
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            ladefile = "C:\Aepfel.JPG"
            bmp = New Bitmap(ladefile)
            PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
            PictureBox2.SizeMode = PictureBoxSizeMode.StretchImage
            PictureBox3.SizeMode = PictureBoxSizeMode.StretchImage
            'Invalidate()
        End Sub

        Private Sub PictureBox1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
            Dim g As Graphics = e.Graphics
            If Button = 1 Then
                PictureBox1.Image = bmp
                Button = 0
            Else
                Exit Sub
            End If
        End Sub

        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Button = 1
            PictureBox1.Invalidate()
        End Sub

        Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            Button = 2
            PictureBox2.Invalidate()
        End Sub

        Private Sub PictureBox2_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox2.Paint
            Dim bitbox2 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            Dim g As Graphics = Graphics.FromImage(bitbox2)

            If Button = 2 Then


                g.DrawRectangle(Pens.Red, 20, 20, 100, 100)
                g.DrawEllipse(Pens.Pink, 20, 20, 110, 110)
                PictureBox2.Image = bitbox2
                bit = PictureBox2.Image
                Button = 0
            Else
                Exit Sub
            End If

        End Sub

        Private Sub PictureBox3_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox3.Paint
            Dim g As Graphics = e.Graphics
            If Button = 3 Then
                PictureBox3.Image = bmp
                Dim breite As Integer = PictureBox2.Width
                Dim hoch As Integer = PictureBox2.Height
                Dim bit As Bitmap = PictureBox2.Image
                Dim r As New Rectangle(0, 0, breite, hoch)
                g.DrawImage(bit, 0, 0)
                Button = 0
                ' in Biturebox2 mit button2_click gezeichnet
                ' g.DrawRectangle(Pens.Red, 20, 20, 100, 100)
                ' g.DrawEllipse(Pens.Pink, 20, 20, 110, 110)
            Else
                g.DrawImage(bit, 0, 0)
                Exit Sub
            End If
        End Sub

        Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
            Button = 3
            PictureBox3.Image = bmp
        End Sub
    End Class

    Sonntag, 17. Februar 2013 18:14
  • Hallo Erdflieger,

    Du hättest schneller eine Antwort bekommen, wenn Du im dafür vorgesehen Visual Basic Forum gefragt hättest -
    denn hier gucken die meisten (ich auch) eher selten rein...

    Zum Problem selbst:
    Eine PictureBox ist in .NET nichts weiter als ein Anzeige-Steuerelement und für mehr als das sollte man es gar nicht verwenden.
    Zeichenoperationen im Paint-Ereignis einer PictureBox werden über das angezeigte Bild gemalt, aber haben nichts damit zu tun.

    Willst Du eine Bitmap manipulieren, so tue es direkt dort (und willst Du es sehen kannst Du eine PictureBox damit versorgen).
    Dein Code etwas reduziert darauf was es wohl tun soll:

    Option Strict On
    Option Infer On
    Option Explicit On
    
    Imports System.Drawing
    Imports System.Windows.Forms
    
    Public Class Form1
        Const OrginalDatei As String = "C:\TEMP\Moor.jpg"
        Const AusgabeDatei As String = "C:\TEMP\MoorRahmen.jpg"
    
        Private OrginalBitmap As Bitmap
        Private RahmenBitmap As Bitmap
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles Me.Load
            OrginalBitmap = New Bitmap(OrginalDatei)
            ' Zeigt das Original an
            Me.PictureBox1.Image = OrginalBitmap
    
            RahmenBitmap = DirectCast(OrginalBitmap.Clone(), Bitmap)
            Using g = Graphics.FromImage(RahmenBitmap)
                Dim bounds = New Rectangle(Point.Empty, RahmenBitmap.Size)
                bounds.Inflate(-20, -20)
                g.DrawRectangle(Pens.Red, bounds)
            End Using
    
            ' Zeigt eine Kopie an mit Rahmen
            Me.PictureBox2.Image = RahmenBitmap
        End Sub
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            ' Zeichnet eine Ellipse dazu
            Using g = Graphics.FromImage(RahmenBitmap)
                Dim bounds = New Rectangle(Point.Empty, RahmenBitmap.Size)
                bounds.Inflate(-20, -20)
                g.DrawEllipse(Pens.Pink, bounds)
            End Using
            ' Die PictureBox neu anzeigen
            Me.PictureBox2.Invalidate()
    
            ' Speichern mit Rahmen und Ellipse
            RahmenBitmap.Save(AusgabeDatei, System.Drawing.Imaging.ImageFormat.Jpeg)
        End Sub
    End Class

    Zur Erläuterung Bereits im Form_Load wird eine Kopie der Bitmap erstellt und ein Rahmen herum gemalt.
    Das Original wird PictureBox1, die mit Rahmen in PictureBox2 zugewiesen (Nummer 3 habe ich gestrichen).

    Drückt man nun auf Button1 wird zusätzlich eine Ellipse gezeichnet.
    Damit die PictureBox es mit  bekommt wird ein Invalidate gesendet
    und (zur Demo) das Ganze gespeichert (Dateinamen oben ändern).

    Entsprechend kannst Du das für alle Zeichenoperationen machen.
    Beachte dass die PictureBox je nach SizeMode die Grafik skaliert und
    wenn Du Mauskoordinaten abgreifen willst, diese nicht unbedingt mit der Bitmap-Größe übereinstimmen.

    Und wenn man komprimierte (Jpeg-)Bilder bearbeitet, sollte man immer vom Orginal
    ausgehen, da jede Speicheroperation mit Verlust behaftet ist.

    Mehr siehe: Erste Schritte mit der Grafikprogrammierung

    Gruß Elmar

    @Moderation: Bitte ins Visual Basic Forum verschieben.

    Sonntag, 17. Februar 2013 19:39
    Beantworter
  • Hallo ,

     danke für die Antwort , war wohl zu schnell mit der Frage und bin im falschen Forum gelandet . Dein Programm ist klar , funktioniert aber nur , wenn PicterBox.sizeMode <>  PictureBoxSizeMode.StretchImage .

    Montag, 18. Februar 2013 14:26
  • Hallo,

    definiere "... funktioniert aber nur ..."
    Die PictureBoxSizeMode Eigenschaft gibt ob bzw. wie eine Bitmap skaliert werden soll, wenn sie nicht in das Steuerelement passt.

    Da es wiederum eher selten ist, dass ein Bild zur Größe einer PictureBox passt, wird es ohne Art von Skalierung nicht gehen.
    Meist wird man die Bild-Steuerelemente sogar so auslegen, dass sie sich an die Fenstergröße anpassen, siehe z. B. Anchor / Dock.

    Natürlich könnte man die Bitmap vorher auf die Größe der PictureBox anpassen:

            Dim size = PictureBox2.ClientSize
            RahmenBitmap = New Bitmap(size.Width, size.Height)
            Using g = Graphics.FromImage(RahmenBitmap)
                ' Bild skalieren
                g.DrawImage(OrginalBitmap, New Rectangle(Point.Empty, size))
    
                Dim bounds = New Rectangle(Point.Empty, RahmenBitmap.Size)
                bounds.Inflate(-20, -20)
                g.DrawRectangle(Pens.Red, bounds)
            End Using
    

    Nur ist das verlustbehaftet und irreversibel.

    Gruß Elmar

    Montag, 18. Februar 2013 15:26
    Beantworter
  • Hallo ,

    hab denThread nach Visual Basic .NET Express-Edition  Forum , wie gewünscht verschoben  .

    Freitag, 22. Februar 2013 05:09