Dateivorschau per Interface IPreviewHandler

    • VB.NET
    • .NET (FX) 4.5–4.8

    Es gibt 48 Antworten in diesem Thema. Der letzte Beitrag () ist von -Franky-.

      Neu

      Hi @-Franky-,

      so ein Dusel - Papierkorb von NAS noch nicht geleert :D

      Hier - als Anlage - ein paar Bilder, welche den IPreview (und mein Programm) killen, wenn ca 20 nacheinander an den IPreview übergeben werden.
      Aber mach Dir nicht zuviel Umstände - wer benutzt heute schon noch die Cliparts vom Office 98?
      Im Win-Explorer werden diese übrigens ohne Vorschaubild, also mit leeren Preview gezeigt.
      Der IRFan kann diese Bilder aber öffnen und anzeigen.
      Auch Paintshop lädt und zeigt diese Bilder an.

      Schönes Rest-Weekend wünsche :)
      Dateien

      Neu

      P.S.
      Zitat:
      "WMF clipart files are NOT Windows wmf files. They are Aldus Placeable
      Metafiles. Aldus Placeable Metafiles are composed of a Windows wmf file
      with a 20 byte header. The header basically gives the file a suggested
      size.
      ...
      The wmf file format is a sequence of records describing how to draw
      an image. Each record converts into a specific Windows function call.
      Therefore a wmf file is actually a program.
      These are the Windows functions that an attacker can craft in a wmf file."


      Vielleicht liest der Win-Explorer den Header vor dem IPreview aus - und wenn dieser 20Bytes gross ist, wird das WMF nicht an die IPreview übergeben.

      Neu

      @Dideldum Probiere mal ein paar kleine Änderungen. Zum einen sind die Funktionen IsAlphaBitmap und GetAlphaBitmapFrom... entfallen. Dafür gibt es was neues.
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Private Function GetBitmapFromHBitmap(nativeHBitmap As IntPtr) As Bitmap
      2. Dim bmp As Bitmap = Bitmap.FromHbitmap(nativeHBitmap)
      3. If Bitmap.GetPixelFormatSize(bmp.PixelFormat) = 32 Then
      4. Dim bmp2 As New Bitmap(GetAlphaBitmap(bmp))
      5. bmp.Dispose()
      6. Return bmp2
      7. End If
      8. Return bmp
      9. End Function
      10. Private Function GetAlphaBitmap(bmpIn As Bitmap) As Bitmap
      11. Dim bmpOut As Bitmap
      12. Dim bmpInData As BitmapData = bmpIn.LockBits(New Rectangle(0, 0, bmpIn.Width, bmpIn.Height), ImageLockMode.ReadOnly, bmpIn.PixelFormat)
      13. bmpOut = New Bitmap(bmpIn.Width, bmpIn.Height, bmpInData.Stride, PixelFormat.Format32bppArgb, bmpInData.Scan0)
      14. bmpIn.UnlockBits(bmpInData)
      15. Return bmpOut
      16. End Function


      Zum anderen könntest auch unter " ' Optional falls die PreviewHandler fehlschlagen!" folgendes machen
      Spoiler anzeigen

      VB.NET-Quellcode

      1. ' Optional falls die PreviewHandler fehlschlagen!
      2. If Not bolRet Then
      3. If m_PreviewFile.ToLower.EndsWith(".wmf") Then
      4. Dim bmp As New Bitmap(m_PreviewFile)
      5. If bmp IsNot Nothing Then
      6. If m_PreviewWindow.BackgroundImage IsNot Nothing Then m_PreviewWindow.BackgroundImage.Dispose()
      7. m_PreviewWindow.BackgroundImageLayout = ImageLayout.Center
      8. m_PreviewWindow.BackgroundImage = bmp
      9. bolRet = True
      10. End If
      11. Else
      12. Dim pIShellItemImageFactory As IntPtr
      13. If SHCreateItemFromParsingName(m_PreviewFile, IntPtr.Zero,
      14. New Guid(IID_IShellItemImageFactory),
      15. pIShellItemImageFactory) = S_OK Then
      16. Dim oIShellItemImageFactory As Object = Marshal.GetObjectForIUnknown(pIShellItemImageFactory)
      17. If oIShellItemImageFactory IsNot Nothing Then
      18. Dim hBitmap As IntPtr
      19. If CType(oIShellItemImageFactory, IShellItemImageFactory).GetImage(New Size(Math.Min(PrevSize.Width, PrevSize.Height),
      20. Math.Min(PrevSize.Width, PrevSize.Height)),
      21. SIIGBF.SIIGBF_RESIZETOFIT, hBitmap) = S_OK Then
      22. If hBitmap <> IntPtr.Zero Then
      23. If m_PreviewWindow.BackgroundImage IsNot Nothing Then m_PreviewWindow.BackgroundImage.Dispose()
      24. m_PreviewWindow.BackgroundImageLayout = ImageLayout.Center
      25. m_PreviewWindow.BackgroundImage = GetBitmapFromHBitmap(hBitmap)
      26. DeleteObject(hBitmap)
      27. bolRet = True
      28. End If
      29. End If
      30. Marshal.ReleaseComObject(oIShellItemImageFactory)
      31. End If
      32. Marshal.Release(pIShellItemImageFactory)
      33. End If
      34. End If
      35. End If


      Damit werden Dir zumindest Deine WMF, die nicht wollen, direkt geladen und auch als Bild angezeigt.
      Mfg -Franky-

      Neu

      Wie cool ist das denn? 8o

      Viiiiielen Dank @-Franky- - Das ist hypersuperoberklasse! :thumbsup:
      So funktioniert es superklasse - auch mit den uralt WMFs.

      Kann man diese WMF bzw. alle Bilder denn auch Formfüllend anzeigen lassen?
      Diese werden im Gegensatz zu anderen Formaten wie z.B. Docs nicht füllend, sondern nur in deren vorgegebener Grösse angezeigt.

      Edit:
      Ich verwende schon:

      VB.NET-Quellcode

      1. Private Sub Resize_WindowsViewer()
      2. If tsc_WindowsViewer.Visible = True Then
      3. tsc_WindowsViewer_PictureBox.Size = tsc_WindowsViewer.ContentPanel.Size
      4. Try
      5. Preview.ResizePreview(tsc_WindowsViewer_PictureBox.Size)
      6. Catch ex As System.Exception
      7. Dim form_fehler As New ICE_Eingabe
      8. form_fehler.Initialisiere(False, My.Resources.ICE_Common_ICEFehler, String.Format(My.Resources.ICE_Main_WindowsPreview_Fehler, ex.Message), MessageBoxButtons.OK, 8)
      9. End Try
      10. End If
      11. End Sub

      Aber das wirkt bei Bildchen nicht, da die WMFs m.W. im Header eine Grösse vorgaben und die anderen Bilder auch klare Dimensionen haben.

      Ich durchblicke zwar nicht wirklich, was Du gemacht hast - aber es funzt perfekt! :D

      Besten Merci! ^^

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

      Neu

      @-Franky-,
      jo, da hast schon recht - ich würde das daher gerne umschaltbar machen - wie in meinem Pic-Editor.

      1. Originalgrösse
      2. Originalgrösse (zentrieren)
      3. Anzeigegrösse (Verhältnis beibehalten)
      4. Anzeigegrösse (Verhältnis ignorieren)

      Aber mit dem Preview.ResizePreview aus meinem vorherigen Script funzt es nicht bei Bildern, nur bei anderen Formaten.
      Weisst Du, wo ich da Hand anlegen könnte?

      Neu

      Hi. Preview.ResizePreview funktioniert nicht bei allen Dateiformaten. Steht auch so als Kommentar im Code. Alternativ musst Du halt eine Weiche für Bilder einbauen damit Bilder nicht über den IPreviewHandler geladen werden. Bilder kannst ja ganz normal mit .NET Mitteln laden und passend skalieren. Allerdings verwendet VB.NET noch GDI+ für Bilder und da sind die Codecs fest vorgegeben. Also nicht erweiterbar. zB kannst Du per GDI+ keine HEIC/HEIF Bilder laden. Wenn dann würde ich auf die Windows Imaging Component (WIC) für Bilder wechseln. WIC kann von Haus aus mehr Bildformate lesen/schreiben und ist durch zusätzliche WIC-Codecs erweiterbar.
      Mfg -Franky-

      Neu

      Hi @-Franky-

      danke Dir - ja, so habe ich das auch gelöst.
      Die User können bei unverschlüsselt gespeicherten Bildern wählen, ob sie diese im IPreview oder dem Pic-Editor angezeigt bekommen wollen.
      Und im Pic-Editor können die ja auch das Anzeigeformat auswählen.

      Zu dem WIC muss ich noch recherchieren - aber ich denke, mit der regulären PicBox reichen die üblichen Bildformate auch aus.

      Vielen Dank für Deine Hilfe :)

      Neu

      Dideldum schrieb:

      Zu dem WIC muss ich noch recherchieren

      Vllt. mal nur so im Hinterkopf behalten falls Du das mal irgendwann benötigst. Auf meinem PC (Win10) kann WIC folgende Bildformate lesen:
      BMP Decoder: *.bmp;*.dib;*.rle
      GIF Decoder: *.gif
      ICO Decoder: *.ico;*.icon
      CUR Decoder: *.cur
      JPEG Decoder: *.jpeg;*.jpe;*.jpg;*.jfif;*.exif
      PNG Decoder: *.png
      TIFF Decoder: *.tiff;*.tif
      DNG Decoder: *.dng
      WMPhoto Decoder: *.wdp;*.jxr
      DDS Decoder: *.dds
      Microsoft HEIF Decoder: *.heic;*.heif;*.hif;*.avci;*.heics;*.heifs;*.avcs;*.avif;*.avifs
      Microsoft Webp Decoder: *.webp
      Microsoft Raw Image Decoder: *.3fr;*.ari;*.arw;*.bay;*.cap;*.cr2;*.cr3;*.crw;*.dcs;*.dcr;*.drf;*.eip;*.erf;*.fff;*.iiq;*.k25;*.kdc;*.mef;*.mos;*.mrw;*.nef;*.nrw;*.orf;*.ori;*.pef;*.ptx;*.pxn;*.raf;*.raw;*.rw2;*.rwl;*.sr2;*.srf;*.srw;*.x3f;*.dng
      Microsoft Camera Raw Decoder: *.arw;*.cr2;*.crw;*.erf;*.kdc;*.mrw;*.nef;*.nrw;*.orf;*.pef;*.raf;*.raw;*.rw2;*.rwl;*.sr2;*.srw;*.dng

      Und folgende schreiben:
      BMP Encoder: *.bmp;*.dib;*.rle
      GIF Encoder: *.gif
      JPEG Encoder: *.jpeg;*.jpe;*.jpg;*.jfif;*.exif
      PNG Encoder: *.png
      TIFF Encoder: *.tiff;*.tif
      WMPhoto Encoder: *.wdp;*.jxr
      DDS Encoder: *.dds
      Microsoft HEIF Encoder: *.heic;*.heif;*.hif
      Mfg -Franky-