では画像をつかってリストアイテムを表示させました。ところがあまり美しくありません。まず画像の形状を考えずにそのまま正方形に変形しているので、長方形の画像が縦や横に細長くなってうまく表示されません。これを改善します。
改善前
GetFileImage(string path)メソッドを以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
public partial class Form1 : Form { // 縦横の比を維持できるように修正した Bitmap GetFileImage(string path) { try { Image image = Image.FromFile(path); Bitmap bitmap = GetListItemImage(image, IconSize); image.Dispose(); return bitmap; } catch { Icon icon = Icon.ExtractAssociatedIcon(path); Bitmap bitmap1 = icon.ToBitmap(); Bitmap bitmap2 = GetListItemImage(bitmap1, IconSize); icon.Dispose(); bitmap1.Dispose(); return bitmap2; } } // フォルダの表示も下記メソッドを使用してイメージを取得する Image GetFolderImage() { SHFILEINFO shinfo = new SHFILEINFO(); IntPtr hSuccess = SHGetFileInfo("", 0, ref shinfo, (uint)System.Runtime.InteropServices.Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON); if(hSuccess != IntPtr.Zero) { Icon appIcon = Icon.FromHandle(shinfo.hIcon); Bitmap bitmap = appIcon.ToBitmap(); return GetListItemImage(bitmap, IconSize); } return null; } // 縦横の比を維持したまま size × size ピクセルのイメージを取得する Bitmap GetListItemImage(Image image, int size) { if(size == -1) size = 16; System.Drawing.Imaging.PixelFormat pf = System.Drawing.Imaging.PixelFormat.Format32bppArgb; Bitmap bitmap = new Bitmap(size, size, pf); Graphics g = Graphics.FromImage(bitmap); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; float fSize = size; if(image.Width < image.Height) { float div = image.Height / fSize; int width = (int)(image.Width / div); g.DrawImage(image, new Rectangle((size - width) / 2, 0, width, size)); } else { float div = image.Width / fSize; int height = (int)(image.Height / div); g.DrawImage(image, new Rectangle(0, (size - height) / 2, size, height)); } g.Dispose(); return bitmap; } } |
結果
これで画像の縦横の比が維持されるので前よりはよくなりましたが、これでもいまいちです。フォルダや画像ファイル以外のファイルアイコンがぼんやりしています。これはどうすることもできないのかと困っていたところ、Windows API Code Packについて解説しているページをみつけました。
これによるとパッケージ マネージャー コンソールから
PM> Install-Package WindowsAPICodePack-Core
PM> Install-Package WindowsAPICodePack-Shell
でインストール。
そして
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public partial class Form1 : Form { Bitmap GetFileImage(string path) { try { // 画像ファイルの処理は同じ Image image = Image.FromFile(path); Bitmap bitmap = GetListItemImage(image, IconSize); image.Dispose(); return bitmap; } catch { var file = Microsoft.WindowsAPICodePack.Shell.ShellFile.FromFilePath(path); file.Thumbnail.FormatOption = Microsoft.WindowsAPICodePack.Shell.ShellThumbnailFormatOption.Default; Bitmap bitmap1 = file.Thumbnail.Bitmap; // 背景が黒くなってしまうのでColor.FromArgb(0)は透明にする bitmap1.MakeTransparent(Color.FromArgb(0)); Bitmap bitmap2 = GetListItemImage(bitmap1, IconSize); bitmap1.Dispose(); return bitmap2; } } Image GetFolderImage() { DriveInfo drive = new DriveInfo("C"); DirectoryInfo[] ds = drive.RootDirectory.GetDirectories(); string folderPath = ds[0].FullName; var file = Microsoft.WindowsAPICodePack.Shell.ShellFolder.FromParsingName(folderPath); file.Thumbnail.FormatOption = Microsoft.WindowsAPICodePack.Shell.ShellThumbnailFormatOption.Default; Bitmap bitmap1 = file.Thumbnail.Bitmap; bitmap1.MakeTransparent(Color.FromArgb(0)); return bitmap1; // API関数は使わない } } |
これだときれいに表示されます。