none
Bilder schnell Einlesen und Verarbeiten RRS feed

  • Frage

  • Hi

    Ich wollte für einen Dateibrowser eine Vorschau für Bilder programmieren,darfür mussen sie geladen und propational Verkleinert werden und dass sollte möglichst schnell und ohne so viel Ram zu ziehen gehen weiß jemand was?


    MFG M. D.
    Samstag, 26. Februar 2011 11:44

Antworten

  • z.B.
    --
    Viele Grüße
    Peter
     
     
    • Als Antwort markiert coder101001 Dienstag, 8. März 2011 16:27
    Samstag, 26. Februar 2011 14:57
  • Hallo,

    ein Beispiel für das Generieren von Thumbnails?

    (Eine PictureBox auf eine Form ziehen):

    Public Class Form1
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim img As Image = Image.FromFile("C:\Users\...\Desktop\tmp\02fz.tgi.png")
        Dim bmp As Bitmap = New Bitmap(img)
        img.Dispose()
    
        'thumbnail mit langer seite = 200px erstellen
        Me.PictureBox1.Image = GetThumbnail(bmp, 200)
      End Sub
    
      Private Function GetThumbnail(ByVal bmp As Bitmap, ByVal longSideLength As Integer) As Bitmap
        Dim faktor As Double = CType(bmp.Width, Double) / CType(bmp.Height, Double)
    
        Dim w As Double = 0
        Dim h As Double = 0
    
        'width > height
        If faktor > 1.0 Then
          w = longSideLength
          Dim faktor2 As Double = CType(longSideLength, Double) / CType(bmp.Width, Double)
          h = faktor2 * bmp.Height
        Else
          h = longSideLength
          Dim faktor2 As Double = CType(longSideLength, Double) / CType(bmp.Height, Double)
          w = faktor2 * bmp.Width
        End If
    
        Dim bOut As Bitmap = Nothing
        If w > 0 And h > 0 Then
          bOut = New Bitmap(CType(Math.Ceiling(w), Integer), CType(Math.Ceiling(h), Integer))
    
          Using g As Graphics = Graphics.FromImage(bOut)
            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            g.DrawImage(bmp, 0, 0, CType(w, Single), CType(h, Single))
          End Using
        End If
    
        Return bOut
      End Function
    
      Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If Not Me.PictureBox1.Image Is Nothing Then
          Me.PictureBox1.Image.Dispose()
        End If
      End Sub
    End Class
    

    Zum Speichern in einer DB, Bild in Byte[] wandeln (z.B in MemoryStream speichern) und den Byte-Array dem Feld korrekten Typs in der DatenBankTabelle zuweisen. Weitere Eigenschaften des Bildes wie Änderungsdatum ebenfalls in der DB speichern und beim weiteren/nächsten "navigieren" des users in das entsprechende Verzeichnis erst die "Änderungskriterien" in der DB für die Bilder überprüfen, dann Bild aus DB laden, oder neuen Thumbnail erstellen und in der DB updaten.

    Viele Grüße,

      Thorsten

    • Als Antwort markiert coder101001 Dienstag, 8. März 2011 16:27
    Donnerstag, 3. März 2011 01:44
  • Hi,

    nein, beim ersten laden (= erstellen) der Thumbnails ist es nicht wirklich schnell, da jedes Bild komplett geladen und verkleinert gezeichnet werden muss. Daher ja das Speichern in einem stream, bzw. einer Datenbank. Wenn die thumbnails erst einmal dort abgelegt worden sind, ist die Anzeige für dieses Verzeichnis dann sehr schnell.

    Das Extrahieren von thumbnails mit System.Drawing.Image.GetThumbnailImage ist hier vielleicht schneller, ich weoß es nicht, ich war mit dieser Methode, bzw. ihren Ergebnissen nicht so ganz zufrieden.

    Vielleicht geht es über WPF und Shell schneller...

    Viele Grüße,

      Thorsten

    • Als Antwort markiert coder101001 Dienstag, 8. März 2011 16:27
    Donnerstag, 3. März 2011 22:39

Alle Antworten

  • SChau dir mal die Möglichkeit an, ThumbNails zu erstellen. Laden musst Du zwar erst einmal das gesamte Bild, kannst dann aber die "Briefmarke" halten und brauchst dadurch viel weniger Ressourcen.

    --
    Peter

    Samstag, 26. Februar 2011 12:48
  • Meinst du:System.Drawing.Image.GetThumbnailImage
    MFG M. D.
    Samstag, 26. Februar 2011 14:22
  • z.B.
    --
    Viele Grüße
    Peter
     
     
    • Als Antwort markiert coder101001 Dienstag, 8. März 2011 16:27
    Samstag, 26. Februar 2011 14:57
  • Diese Methode liefert aber nicht immer brauchbare Ergebnisse, da sie ggf. in der Bilddatei enthaltene Thumbnailbildchen extrahiert, die oft von schlechter Qualität sind.

    Eventuell ist folgende Herangehensweise für Dich brauchbar:

    Thumbnail Extraction Using the Shell
    http://vbaccelerator.com/article.asp?id=4513

    Beste Grüße,
    Herfried K. Wagner


    Herfried K. Wagner [MVP]
    Dienstag, 1. März 2011 21:34
  • Hi,

    Du kannst die Bilder auch mittels gdi+ als thumbnails zeichnen, da hast Du die volle Kontrolle. Auf jeden Fall würde ich erstellte thumbnails in einer Datenbank o.ä. speichern, um sie beim nächsten Mal dann schnell laden zu können.

    Viele Grüße,

      Thorsten

    Dienstag, 1. März 2011 23:47
  • Könntest du mal ein Beispiel posten?
    MFG M. D.
    Mittwoch, 2. März 2011 20:23
  • Hallo,

    ein Beispiel für das Generieren von Thumbnails?

    (Eine PictureBox auf eine Form ziehen):

    Public Class Form1
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim img As Image = Image.FromFile("C:\Users\...\Desktop\tmp\02fz.tgi.png")
        Dim bmp As Bitmap = New Bitmap(img)
        img.Dispose()
    
        'thumbnail mit langer seite = 200px erstellen
        Me.PictureBox1.Image = GetThumbnail(bmp, 200)
      End Sub
    
      Private Function GetThumbnail(ByVal bmp As Bitmap, ByVal longSideLength As Integer) As Bitmap
        Dim faktor As Double = CType(bmp.Width, Double) / CType(bmp.Height, Double)
    
        Dim w As Double = 0
        Dim h As Double = 0
    
        'width > height
        If faktor > 1.0 Then
          w = longSideLength
          Dim faktor2 As Double = CType(longSideLength, Double) / CType(bmp.Width, Double)
          h = faktor2 * bmp.Height
        Else
          h = longSideLength
          Dim faktor2 As Double = CType(longSideLength, Double) / CType(bmp.Height, Double)
          w = faktor2 * bmp.Width
        End If
    
        Dim bOut As Bitmap = Nothing
        If w > 0 And h > 0 Then
          bOut = New Bitmap(CType(Math.Ceiling(w), Integer), CType(Math.Ceiling(h), Integer))
    
          Using g As Graphics = Graphics.FromImage(bOut)
            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            g.DrawImage(bmp, 0, 0, CType(w, Single), CType(h, Single))
          End Using
        End If
    
        Return bOut
      End Function
    
      Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If Not Me.PictureBox1.Image Is Nothing Then
          Me.PictureBox1.Image.Dispose()
        End If
      End Sub
    End Class
    

    Zum Speichern in einer DB, Bild in Byte[] wandeln (z.B in MemoryStream speichern) und den Byte-Array dem Feld korrekten Typs in der DatenBankTabelle zuweisen. Weitere Eigenschaften des Bildes wie Änderungsdatum ebenfalls in der DB speichern und beim weiteren/nächsten "navigieren" des users in das entsprechende Verzeichnis erst die "Änderungskriterien" in der DB für die Bilder überprüfen, dann Bild aus DB laden, oder neuen Thumbnail erstellen und in der DB updaten.

    Viele Grüße,

      Thorsten

    • Als Antwort markiert coder101001 Dienstag, 8. März 2011 16:27
    Donnerstag, 3. März 2011 01:44
  • Das ist aber nicht wirklich schneller als das was ich bisher habe.Ich schätze es liegt nicht an der berabeitung des Bildes sondern am laden geht das laden des Bildes auch anders als über image.fromfile?

    MFG M. D.
    Donnerstag, 3. März 2011 18:48
  • Hi,

    nein, beim ersten laden (= erstellen) der Thumbnails ist es nicht wirklich schnell, da jedes Bild komplett geladen und verkleinert gezeichnet werden muss. Daher ja das Speichern in einem stream, bzw. einer Datenbank. Wenn die thumbnails erst einmal dort abgelegt worden sind, ist die Anzeige für dieses Verzeichnis dann sehr schnell.

    Das Extrahieren von thumbnails mit System.Drawing.Image.GetThumbnailImage ist hier vielleicht schneller, ich weoß es nicht, ich war mit dieser Methode, bzw. ihren Ergebnissen nicht so ganz zufrieden.

    Vielleicht geht es über WPF und Shell schneller...

    Viele Grüße,

      Thorsten

    • Als Antwort markiert coder101001 Dienstag, 8. März 2011 16:27
    Donnerstag, 3. März 2011 22:39