picturebox ausschneiden

22/09/2007 - 16:10 von dr. dietrich seidl 1959 | Report spam
hallo, kann mir jemand zeigen, wie man ein bild ausschneidet

Private _pic As New Bitmap("D:\Eigene Dateien\cd\beauty.jpg")

ich habe zwei pictureboxen
'cover
With Me._pb
.Name = "cover"
.Location = New System.Drawing.Point(10, 15)
.Size = New System.Drawing.Size(CInt(721 / 2), h)
.Cursor = Cursors.Default
.AllowDrop = True
.Enabled = True
.SizeMode = PictureBoxSizeMode.Zoom 'optimal unter behalt
der relationen
.BorderStyle = BorderStyle.FixedSingle
.Image = _pic
AddHandler .MouseDown, AddressOf Me.pb_MouseDown
AddHandler .MouseMove, AddressOf Me.pb_MouseMove
AddHandler .MouseUp, AddressOf Me.pb_MouseUp
End With
Me.Controls.Add(Me._pb)

'cover2
With Me._pb2
.Name = "cover2"
.Location = New System.Drawing.Point(380, 15)
.Size = New System.Drawing.Size(CInt(721 / 2), h)
.Cursor = Cursors.Default
.AllowDrop = True
.Enabled = True
.SizeMode = PictureBoxSizeMode.Zoom 'optimal unter behalt
der relationen
.BorderStyle = BorderStyle.FixedSingle
AddHandler .Paint, AddressOf Me.pb_Paint
End With
Me.Controls.Add(Me._pb2)

über mousedown move und up erzeuge ich eine rubberbox

Private Sub drawrubberbox()

_rubbervisible = True
'rubberbox zeichnen
ControlPaint.DrawReversibleFrame(New Rectangle(Me._rubberpos,
Me._rubbersize), Color.White, FrameStyle.Dashed)

End Sub

Private Sub removerubberbox()

'wenn sichtbar dann löschen durch neues negativzeichnen und
einstellen der variable Me._rubbervisible
If _rubbervisible = True Then ControlPaint.DrawReversibleFrame(New
Rectangle(Me._rubberpos, Me._rubbersize), Color.White, FrameStyle.Dashed)

Me._rubbervisible = False

End Sub

Private Sub pb_MouseDown(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs)

Me._rubbercancel = False
Me._rubberpos_orig = New Point(e.X, e.Y)
Me._rubberpos = Me._pb.PointToScreen(Me._rubberpos_orig) 'umrechnen
Me._rubbersize = New Size(0, 0)

'startrechteck zeichnen
Me.drawrubberbox()

End Sub

Private Sub pb_MouseMove(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs)

If e.Button <> MouseButtons.None And Me._rubbercancel = False Then

Dim __x As Integer = e.X
Dim __y As Integer = e.Y

'bisheriges Rechteck löschen
Me.removerubberbox()

'größe des neuen rechteckes ermitteln
If __x < 0 Then __x = 0
If __x > Me._pb.ClientSize.Width Then __x =
Me._pb.ClientSize.Width
If __y < 0 Then __y = 0
If __y > Me._pb.ClientSize.Height Then __y =
Me._pb.ClientSize.Height

'neues rechteck zeichnen
'Me._rubbersize = New Size(__x - Me._rubberpos_orig.X, __y -
Me._rubberpos_orig.Y)

Me._rubbersize = New Size(__x - Me._rubberpos_orig.X, __y -
Me._rubberpos_orig.Y)
Me.drawrubberbox()

End If

End Sub

Private Sub pb_MouseUp(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp

If Me._rubbercancel Then Exit Sub

Me.Refresh()

End Sub

im paintereignis von Me._pb2 soll der ausschnitt wiedergegeben werden

Private Sub pb_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs)

Dim __gr As Graphics = e.Graphics

' Ausschnitt nur zeichnen, wenn ein gültiges Auswahlrechteck vorliegt
If Me._rubbersize.Width <= 0 Or Me._rubbersize.Height <= 0 Then Exit
Sub

Me._zf = 2


'quellrechteck für den Ausschnitt In Bildkoordinaten
Dim __qrect As New Rectangle(CInt(Me._rubberpos_orig.X),
CInt(Me._rubberpos_orig.Y), CInt(Me._rubbersize.Width),
CInt(Me._rubbersize.Height))

'zielrechteck für den Ausschnitt In Bildkoordinaten
Dim __zrect As New Rectangle(CInt(__qrect.X), CInt(__qrect.Y),
CInt(__qrect.Width), CInt(__qrect.Height)) 'zielgröße

'bild das pbox inhalt darstellt, mit leerflàchen
Dim bmp As New Bitmap(Me._pb.Image, Me._pb.Width, Me._pb.Height)

__gr.DrawImage(Me._pic, __zrect, __qrect, GraphicsUnit.Pixel)
'ziel,quelle


End Sub


leider sehe ich in _pb2 nicht den selben ausschnitt wie in der rubberbox von
_pb
wenn ich in _pb den PictureBoxSizeMode auf normal stelle ist das kein
problem, aber leider kann ich nicht auf zoom verzichten

herzlich grüße dr seidl
 

Lesen sie die antworten

#1 Karsten Sosna
23/09/2007 - 08:16 | Warnen spam
leider sehe ich in _pb2 nicht den selben ausschnitt wie in der rubberbox
von
_pb
wenn ich in _pb den PictureBoxSizeMode auf normal stelle ist das kein
problem, aber leider kann ich nicht auf zoom verzichten



Hallo Dietrich,
auch wenn Du SizeMode ànderst, so àndert es nichts an der Größe des Image.
Das bleibt immer gleich groß. Es bleibt also nichts anderes, als das
Rectangle, welches "ausgeschnitten" wird, selber zu berechnen. Die
PictureBox benutzt die Überladung <Graphics>.DrawImage(Image, Rectangle) zum
Zeichnen. Berechnet wird das Rectangle so(Quelle: Lutz Roeder's
.NET-Reflector):
\\\
Dim rectangle As Rectangle
'...
Dim size As Size = Me.image.Size
Dim zoom As Single = Math.Min(CSng((CSng(MyBase.ClientRectangle.Width) /
CSng(size.Width))), CSng((CSng(MyBase.ClientRectangle.Height) /
CSng(size.Height))))
rectangle.Width = CInt((size.Width * zoom))
rectangle.Height = CInt((size.Height * zoom))
rectangle.X = ((MyBase.ClientRectangle.Width - rectangle.Width) / 2)
rectangle.Y = ((MyBase.ClientRectangle.Height - rectangle.Height) / 2)
///
Ob das viele Casten in der Berechnung wirklich stattfindet kann ich mir
eigentlich nicht vorstellen, denn das funktioniert auch:
\\\
Dim zoom As Single = CSng(Math.Min(MyBase.ClientRectangle.Width /
size.Width, MyBase.ClientRectangle.Height / size.Height))
///
Bedenke das Beide Berechnungen unterschiedliche Ergebnisse liefern können,
denn einmal wird mit Single und einmal mit Double gerechnet. Das der
Reflector das mit dem Casten nicht ganz so drauf hat sieht man an den
Zuweisungen rectangle.X und rectangle.Y. "rectangle" ist vom Typ Rectangle,
also Ganzzahlen. Die Berechnung ergibt aber einen Double-Wert. Also scheint
dort CInt zu fehlen.
Die Berechnung des Zooms sollte aber stimmen, da nur ein Pixel Abweichnung
ausreicht um das Ergebnis zu verfàlschen. Also austesten. Andere Möglichkeit
ist es die Zoom-Funktionalitàt komplett selber zu übernehmen.
Gruß Scotty

Ähnliche fragen