提取文件圖標


 

FileToIcon.zip 1

FileToIcon.exe

 

 

 

 

 

上面連個壓縮文件圖標和exe圖標都是這樣生成的

我改寫了一下用來獲取文件圖標,用C#,winform實現。不過寫的有點爛,希望大家積極改進。(后面有譯文)

我不斷的設置斷點,由於我想保存超大圖標所以首先改變size

文件大小int size = 128;

這樣就會使程序運行至public static Bitmap loadJumbo(string lookup)

方法獲取我要的特大圖標。

我設置了public static Bitmap bmp;

靜態變量,保存我要的圖標。

隨后回到Fom1中,當點擊執行時,

FileToIconConverter.Convert(textBox1.Text);

FileToIconConverter.bmp.Save(textBox2.Text, ImageFormat.Png);

方法一:生成bmp

方法二:保存到指定文件夾

生成的圖標為256*256

你也可以將原文件名替換成文件夾名,就可以生成文件夾圖標了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

源文件來自:WPF Filename To Icon Converter

開發:C#,.net 3.5,WPF

Introduction

介紹

This article describes FileToIconConverter, which is a MultiBinding Converter that can retrieve an Icon from system based on a filename (exist or not) and size.

該文描述的是文件轉圖片程序使用方法,根據文件名和大小,通過多重綁定轉換器,提取圖標的功能。

Background

背景

I am working on a file explorer, which shows a file list, inside the filelist, which requires to place a file icon next to each file in a folder.

我正在做一個可以顯示文件列表的文件管理器,在這個文件列表中,要求文檔中的文件圖標兩兩相鄰。

In my first implementation, I added an Icon property in the data model of the file, it works fine.  When I implements the Icon View, I added a Large Icon property, then I added Thumbnail property for the Thumbnail view support.

初次嘗試,我為文件數據模型增加一個圖標屬性,效果不錯。但當我需要是實現顯示圖標,我又添加大圖標屬性,然后又添加了縮略圖屬性,用來支持縮略圖顯示。

This implementation has a number of problems:

  • Three Bitmaps (Icon, LargeIcon, Thumbnail), five if we include ExtraLarge and Jumbo in the Datamodel. They are usually duplicated (e.g. folder with JPGs), and unused (who will change views regularly anyway).
  • The code that is not related to the DataModel shouldn't be placed there.
  • Icon resize (like the slidebar in Vista Explorer) becomes very difficult, as there are 3-5 properties to bind with.

這次出現了幾個問題

  • 三個Bitmap位圖,(圖標(Icon),大圖標(LargeIcon),縮略圖(Thumbnail)),如果再加上超大圖標(ExtraLarge)和特大圖標(Jumbo)的話,就有五種位圖了。他們之間會存在重復,或未使用的情況。
  • 與數據模型有關的代碼不該放在實現部分。
  • 圖標可以縮放,由於有3-5種不同的位圖顯示,這會使實現變得困難。

So I changed my design. I believe a converter with cache is best suited for this purpose.

  • Icons are cached in a dictionary, file with same extension occupied only one copy of memory.
  • Load on demand (e.g. if the view needs an Icon, then load Icon only).
  • Reusable, coder just needs to bind filename and size

於是我改變了我的程序設計方法,我想把它做成一個圖標緩存的轉換器應該能達到我的目的

  • 圖標緩存在dictionary類中,相同擴展名的文件值占用一次內存。
  • 根據需要載入圖標(例如:如果需要這種圖標,只要轉換成這種就好了)。
  • 可重用性,程序員,只需要綁定文件名和文件大小就可以獲得文件的五種圖標。

Thumbnails are loaded in separate thread (no longer jam the UI). Jumbo icon is shown before the thumbnail is loaded.

縮略圖有單獨的線程載入(這樣就不會與UI載入擁堵了),特大圖標在縮略圖載入前顯示出來。

How to Use? 

怎樣使用呢?

The converter is a MultiBinding Converter, which takes 2 parameters, filename and size:

  • Filename need not necessarily exist (e.g. abc.txt works)
  • Size determines which icon to obtain (Optional)
    • <= 16 - Small
    • <= 32 - Large
    • <= 48 - Extra Large
    • <= 100 - Jumbo
    • Otherwise, Thumbnail if it is an image, Jumbo if it is not an image. 

多重綁定轉換器,定義了兩個參數,filename,文件名和size文件大小。

  • 文件不要求一定存在,例如只要給定文件名和擴展名,就可以顯示圖標了。
  • 文件大小選擇性的決定獲取那種圖標。
    • <= 16 – 小圖標
    • <= 32 – 大圖標
    • <= 48 – 超大圖標
    • <= 100 – 特大圖標
    • 否則,如果是圖片文件則取縮略圖,不是圖片則取特大圖標
<t:FileToIconConverter x:Name="converter" />
<Slider x:Name="slider" ... />
<TextBlock x:Name="fileName" ... />
<Image Height="{Binding ElementName=slider, Path=Value}" 
       Width="{Binding ActualHeight}" Stretch="Uniform">
    <Image.Source>
        <MultiBinding Converter="{StaticResource converter}">
            <Binding ElementName="fileName" Path="Text"/> <!-- FileName -->
            <Binding ElementName="slider" Path="Value" /> 
                            <!-- Size, use DefaultSize if not specified --> 
        </MultiBinding >
    </Image.Source>
</Image> 

 

How It Works?

如何工作的?

MultiBinding Converter is similar to the normal Binding IValueConverter except it takes multiple value to convert, the Convert is as shown below:

多重綁定轉換器與常用的實現IValueConverter 接口類似,除非有多個值需要轉換,轉換方法如下:

public object Convert(object[] values, Type targetType, 
   object parameter, CultureInfo culture)
{
    int size = defaultSize;
    if (values.Length > 1 && values[1] is double)
      size = (int)(float)(double)values[1];
            
    if (values[0] is string)
      return imageDic[getIconKey(values[0] as string, size)];
    else return imageDic[getIconKey("", size)];
}


  • parameter 2 is converted to a local variable named size.
  • parameter 1 is converted to a Icon in imageDic with a key (getIconKey() method, see below). 
  • 參數1轉換成imageDic(字典類)中的帶鍵圖標項
  • 參數2轉換成常量Size圖片大小

Icons are retrieved based on Size and Extensions

  • Thumbnail
    • Image - Return WritableBitmap (new in .NET 3.5), which acts like BitmapImage but allows change after initialization.
    • Otherwise - treat as Icon
  • Jumbo / ExtraLarge
  • Small / Large
    • Load using SHGetFileInfo (Win32 API) directly. I try to avoid SystemImageList because it has its own cache system which will cause some overhead.
  • 根據圖標大小和擴展名提取圖標
  • 縮略圖
    • 圖片返回WritableBitmap .Net 3.5中的新類),與位圖圖片BitmapImage 類相似,不過此類初始化后可變,類似於Stringbuilder
  • 特大圖標和超大圖標
    • 所有文件(包括Exe文件)都是加載至SystemImageList
  • 小圖標/大圖標
    • 使用Win32API中的SHGetFileInfo加載圖片 。這是為了盡量避免都使用 SystemImageList  ,導致緩存占用過多

There are two caches, iconCache and thumbnailCache, all Icons and thumbnail are stored in cache.

  • iconCache is static, for small - Jumbo Icons, common for all FileToIconConverter.
  • thumbnailCache is instanced, for thumbnail, you can call ClearInstanceCache() method to clear this cache.
  • addToDic() method will add the Icon or Thumbnail (from getImage()) to its cache
  • returnKey() method will return a key for dictionary based on fileName and size,
    • e.g. (".txt+L" for Large Text Icon, ".jpg+S" for Small JPEG icon)
  • loadBitmap() method takes a Bitmap and return a BitmapSource. It's actually callingImaging.CreateBitmapSourceFromHBitmap() method, and is required because Image UIelement does not take a bitmap directly.

包括兩種兩種圖標緩存,iconCachethumbnailCache,所有圖標和縮略圖都保存在內存里。

  • iconCache  是靜態的,對於從小到特大之間的圖標, FileToIconConverter來說都是公用的。
  • thumbnailCache  是實例化生成的,對於縮略圖,可以調用ClearInstanceCache() 清除實例內存。
  • addToDic()  方法將圖標或是縮略圖添加到緩存中
  • returnKey() 方法返回基於filenamesize生成的鍵key(例如".txt+L"表示大文本圖標,".jpg + S"表示小位圖圖標)
  • loadBitmap() 方法如入Bitmap,返回BitmapSource實際上是調用了Imaging.CreateBitmapSourceFromHBitmap()方法,這是由於圖片UIelement 不直接讀入 Bitmap 才采用的方法。

getImage() method retrieves Icon and Thumbnail, its thumbnail loading code looks like below:

getImage() 方法更新圖標和縮略圖,載入縮略圖的代碼如下所示:

//Load as jumbo icon first.                         

WriteableBitmap bitmap = new WriteableBitmap

        (addToDic(fileName, IconSize.jumbo) as BitmapSource);

ThreadPool.QueueUserWorkItem(new WaitCallback(PollThumbnailCallback), 

    new thumbnailInfo(bitmap, fileName));

return bitmap;

The code will try to load the jumbo icon first, which is usually cached already, and much faster to load not cache, then when the processor is free, it will call PollThumbnailCallback() in background thread. This implementation will prevent UI thread hogging problem.

該段代碼嘗試首先載入早以緩存的特大圖標,這樣可以加快速度,然后當處理器空閑時,調用PollThumbnailCallback() 后台線程運行,這可以解決UI線程受阻的問題。

PollThumbnailCallback() method is not too complicated. It actually gets and resizes the thumbnail bitmap (line 4-8), turns it to BitmapSource (Line 9-C), and writes it to the WriteableBitmap obtained (Line 6, D-Q). Line M to Line Q is executed in UI thread, so the only work that is required to process the writeBitmap is placed there.

PollThumbnailCallback() 方法不是很復雜,實際上只是得到和縮放位圖bitmap縮略圖,生成BitmapSource 並把它寫入WriteableBitmap ,第M-N行執行UI線程,所以唯一要做的就是運行writeBitmap方法。

private void PollThumbnailCallback(object state)
2) {
3)   //Non UIThread
4)   thumbnailInfo input = state as thumbnailInfo;
5)   string fileName = input.fullPath;
6)   WriteableBitmap writeBitmap = input.bitmap;

7)   Bitmap origBitmap = new Bitmap(fileName);
8)   Bitmap inputBitmap = resizeImage(origBitmap, new System.Drawing.Size(256, 256));
9)   BitmapSource inputBitmapSource = 
	Imaging.CreateBitmapSourceFromHBitmap(inputBitmap.GetHbitmap(),
A)   IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
B)   origBitmap.Dispose();
C)   inputBitmap.Dispose();

D)   int width = inputBitmapSource.PixelWidth;
E)   int height = inputBitmapSource.PixelHeight;
F)   int stride = width * ((inputBitmapSource.Format.BitsPerPixel + 7) / 8);

G)   byte[] bits = new byte[height * stride];
H)   inputBitmapSource.CopyPixels(bits, stride, 0);
I)   inputBitmapSource = null;

J)   writeBitmap.Dispatcher.Invoke(DispatcherPriority.Background,
K)   new ThreadStart(delegate
L)   {
M)      //UI Thread
N)      Int32Rect outRect = new Int32Rect(0, 
	(int)(writeBitmap.Height - height) / 2, width, height);
O)      writeBitmap.WritePixels(outRect, bits, stride, 0);
P)    }));
Q) } 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM