2011-10-02 3 views
5

Sto usando WindowsAPICodePack, ottenendo Thumbnail di ShellFile. Ma alcuni di quelli che sembrano icone generiche hanno uno sfondo nero. Quindi lo trasformo in una bitmap e imposta il nero come trasparente.Come rimuovere il colore di sfondo delle "icone" ShellFile, ma non delle miniature "reali"

Il problema è che quando si tratta di una miniatura di un'immagine, non dovrebbe farlo. Come posso distinguere una miniatura reale da un'icona?

Il mio codice:

ShellFile sf = ShellFile.FromFilePath(path); 
Bitmap bm = sf.Thumbnail.MediumBitmap; 
bm.MakeTransparent(Color.Black); 

Grazie

+2

difficile vedere come MakeTransparent può funzionare bene sulle icone che contengono il nero. Anyhoo, usa la proprietà FormatOption per chiedere prima solo un'icona. Se fallisce, chiedi una miniatura. –

+0

@Hans a) Grazie. Esattamente quello che stavo cercando. (ma prima chiedo una miniatura - c'è sempre un'icona). b) C'è un altro modo per sbarazzarsi del colore di sfondo? Altrimenti, credo di poter sempre ottenere un'icona invece di una bitmap, ora che so che non sarà una miniatura. – ispiro

risposta

3

Si può affrontare questo problema da un'altra angolazione. È possibile forzare ShellFile.Thumbnail per estrarre solo l'immagine di anteprima se esiste o forzarla per estrarre l'icona dell'applicazione associata.

Così il vostro codice sarebbe simile a questa:

Bitmap bm; 
using (ShellFile shellFile = ShellFile.FromFilePath(filePath)) 
{ 
    ShellThumbnail thumbnail = shellFile.Thumbnail; 

    thumbnail.FormatOption = ShellThumbnailFormatOption.ThumbnailOnly; 

    try 
    { 
     bm = thumbnail.MediumBitmap; 
    } 
    catch // errors can occur with windows api calls so just skip 
    { 
     bm = null; 
    } 
    if (bm == null) 
    { 
     thumbnail.FormatOption = ShellThumbnailFormatOption.IconOnly; 
     bm = thumbnail.MediumBitmap; 
     // make icon transparent 
     bm.MakeTransparent(Color.Black); 
    } 
} 
+1

"gli errori si possono verificare con windows api chiamate quindi basta saltare" - questa è una buona pratica? – BudBrot

+0

È possibile catturare solo una COMException con HResult 0x8004B200 come questo: 'catch (InvalidOperationException ex) { \t COMException comException = ex.GetBaseException() come COMException; \t if (comException.ErrorCode! = Deselezionato ((int) 0x8004B200)) \t \t lancio; \t // TODO: Fai qualcosa } ' –