Picturebox skaliert nicht sauber

  • VB.NET

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von Pasta.

    Picturebox skaliert nicht sauber

    Moin,

    ich habe hier ein kleines Darstellungsproblem, wenn ich ein relativ kleines Bild (hier im Beispiel 5x5 Pixel) in eine Picturebox lade, und diese dann zusammen mit der hellroten Form vergrößere:



    Eigentlich dürfte der weiße Hintergrund der Picturebox gar nicht zu sehen sein, da die SizeMode Eigenschaft auf Stretchimage steht. Und es sieht so aus, als ob das Bild um einen halben Pixel nach links gerutscht ist.

    Bei größeren Bildern tritt das Problem nicht / weniger stark auf.

    Gibt's da eine Lösung für? Ich möchte nämlich an Hand der Mausposition die RBG-Werte auslesen, und das ist mit diesem Rand und der Verschiebung zwar möglich, aber die Darstellung stimmt halt nicht ganz.
    @Theckwolf Eine Form nach exakt Deinen Angaben mit diesem Bild sieht bei mir so aus:

    Bitte beschreibe zunächst präzise, was für Controls mit welchen Properties Du in Deiner Form hast.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Ich habe beim ersten Bild eine Picturebox genommen, bei der man den Interpolationsmode auf Nearest Neighbour setzen kann.

    Die Form ist eine normale Form, dessen Hintergrund ich zur besseren Übersicht rot gefärbt habe

    Hier nochmal ein Bild mit einer Standard-Picturebox direkt aus dem Werkzeugkasten und SizeMode StretchImage:



    Hier sieht man auch teilweise den weißen Hintergrund der Box am Bildrand.

    Original 5x5 Bild:


    Theckwolf schrieb:

    Ich habe beim ersten Bild eine Picturebox genommen, bei der man den Interpolationsmode auf Nearest Neighbour setzen kann.
    Was ist das für eine?
    Kannst Du deren Code posten?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    *unnötiges Zitat entfernt*

    VB.NET-Quellcode

    1. Imports System.Drawing.Drawing2D
    2. Imports System.Windows.Forms
    3. Public Class PictureBoxInterpolationMode
    4. Inherits PictureBox
    5. Public Property InterpolationMode() As InterpolationMode
    6. Get
    7. Return m_InterpolationMode
    8. End Get
    9. Set(value As InterpolationMode)
    10. m_InterpolationMode = value
    11. End Set
    12. End Property
    13. Private m_InterpolationMode As InterpolationMode
    14. Protected Overrides Sub OnPaint(paintEventArgs As PaintEventArgs)
    15. paintEventArgs.Graphics.InterpolationMode = InterpolationMode
    16. MyBase.OnPaint(paintEventArgs)
    17. End Sub
    18. End Class

    *VB-BBCode eingefügt*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    @Theckwolf Sorry, weder mit JPG noch mit PNG kann ich Deinen Effekt reproduzieren.
    Mach mal ein kleines Testprojekt, das diesen Effekt reproduziefrt und häng das als ZIP dran.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ok, hab ein kleines Testprojekt dazu erstellt:

    - Eine Form mit rotem Hintergrund
    - Eine Picturebox mit grünem Hintergrund, SizeMode Stretchimage und Anchor Top, Left, Bottom, Right
    - In der Picturebox das 5x5 Bild (bestehend aus gelben / schwarzen Farben)

    Man sieht deutlich den grünen Hintergrund der Picturebox, obwohl das schwarz-gelbe Bild gestretcht sein sollte.



    Ich habe die Vermutung, dass das hochskalieren intern mit DirectX geschieht, und ich meine mal gelesen zu haben, dass bei DirectX die Grafiken um einen halben Pixel verschoben sind?
    Und die grüne Farbe kommt durch falsches oder Abrunden der neuen Bildgröße + Interpolation mit der Hintergrundfarbe.
    Dateien
    • StretchImage.zip

      (80,22 kB, 115 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Theckwolf“ ()

    @Theckwolf Nutze bitte die Upload-Funktion des Studios (Erweiterte Antwort => Dateianhänge => Hochladen), wir mögen keine werbeverwanzten Hoster.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Theckwolf OK. Editiere bitte Deinen obigen Post und schmeiß den Link raus.
    -----
    Sorry, das Verhalten Deines Programms ist so wie ich es erwarte. Nix komisches.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Sieht das Programm bei dir auch so aus, wie auf dem zuletzt von mir geposteten Screenshot?

    Wenn ja, dann ist dieses Verhalten wohl kein Bug sondern ein Feature...

    Stört das sonst niemanden, dass das Bild nicht sauber gestretcht wird? Wenn das interpolierte Bild wenigstens die komplette Picturebox abdecken würde anstatt ein Stück Rand durchzulassen...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Theckwolf“ ()

    @Theckwolf Ja, es sieht genau so aus, und wenn ich die Größe des Fensters verändere, geht alles wie erwartet mit.
    Allerdings hast Du im Projekt eine schnöde PictureBox verwendet, nicht aber Deine PictureBoxInterpolationMode.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Theckwolf schrieb:

    PictureBoxInterpolationMode
    Du arbeitest mit dem Modus NearestNeighbor, da ist das so.
    Füge mal eine ComboBox in Deine Form ein und dann dies:

    VB.NET-Quellcode

    1. Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
    2. Dim mode As Drawing2D.InterpolationMode = DirectCast(ComboBox1.SelectedIndex, Drawing2D.InterpolationMode)
    3. Me.PictureBox1.InterpolationMode = mode
    4. Me.PictureBox1.Invalidate()
    5. End Sub
    6. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    7. For i = 0 To 7
    8. Dim mode As Drawing2D.InterpolationMode = DirectCast(i, Drawing2D.InterpolationMode)
    9. ComboBox1.Items.Add(mode.ToString)
    10. Next
    11. ComboBox1.SelectedIndex = 0
    12. End Sub

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Ich glaube, du misverstehst mein "Problem".

    Mir ist bekannt, dass mit NearestNeighbor das Bild grobkörnig erscheint (genau das will ich ja bezwecken) und dass man die Interpolationsmodi umschalten kann.

    Mich stört dabei nur, dass das gestretchte Bild nicht sauber auf die PictureBox abgebildet wird (egal bei welchem InterpolationMode).

    Da liegt Fakiz mit seiner Antwort wahrscheinlich näher dran.

    @Fakiz

    Hättest du evtl. ein kurzes Beispiel dazu?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Theckwolf“ ()

    Theckwolf schrieb:

    Ich glaube, du misverstehst mein "Problem".
    Jou.
    Allerdings wird mit diesem Code hier das Bild nicht besser:

    VB.NET-Quellcode

    1. Protected Overrides Sub OnPaint(e As PaintEventArgs)
    2. e.Graphics.InterpolationMode = Me.InterpolationMode
    3. e.Graphics.PageUnit = GraphicsUnit.Pixel
    4. 'MyBase.OnPaint(e)
    5. Dim w = Me.Image.Width
    6. Dim h = Me.Image.Height
    7. e.Graphics.DrawImage(Me.Image, Me.ClientRectangle, 0, 0, w, h, GraphicsUnit.Pixel)
    8. End Sub
    Nimm mal ein etwas größeres Bild (20 x 20) und ein sehr viel größeres Bild. Da wird es besser. :thumbsup:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Nimm mal ein etwas größeres Bild (20 x 20) und ein sehr viel größeres Bild. Da wird es besser.


    Ja, weiß ich, das hab ich auch schon im ersten Post geschrieben. :)

    Aber das soll ein Zoom-Fenster werden, bei dem man eben extra auch kleine Bildausschnitte 1:1 anzeigen lassen können soll.

    Kann doch nicht sein, dass es dafür bisher noch keine schnelle Lösung gibt.
    RodFromGermany hat ja schon fast eine 1:1 Version meines Versuchs gepostet. Allerdings habe ich das mit einer Normalen PictureBox versucht. Als GraphicsUnit habe ich Document verwedet und an stelle des Rectangle ein RectangleF.
    Spoiler anzeigen

    C#-Quellcode

    1. e.Graphics.DrawImage(
    2. Properties.Resources._5x5_jpg, new RectangleF(0, 0, (float)pictureBox1.Width, (float)pictureBox1.Height),
    3. new RectangleF(0, 0, (float)Properties.Resources._5x5_jpg.Width, (float)Properties.Resources._5x5_jpg.Height),
    4. GraphicsUnit.Document);


    Bilder
    • preview.PNG

      97,21 kB, 584×303, 108 mal angesehen
    @Theckwolf Was genau willst Du denn erreichen?
    Du kannst doch die Instanz des Bildes zu Fuß auf eine minimale Größe stretchen und die dann anzeigen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!