文章目錄
- 1. 將剪貼簿內的圖片儲存到檔案
- 2. 監聽剪貼簿變化的事件
- 3. 檔案雷同判別
C#Winform+WindowsAPI做個剪貼簿無縫自動儲存器(視頻利器)
利用C#和Window API做了個自動儲存剪貼簿內的圖片的工具,用在給視頻上是最好不過的了。共用之。
點擊Start按鈕,就會在剪貼簿內容發生變化時自動把儲存到指定位置(儲存為jpg格式的圖片),並且以指定的字串作為檔案的首碼,後面跟上序號。所以這個工具是和PrtSc截屏鍵緊密結合使用的,按一次PrtSc,就儲存一張圖片。就算一直按著不放,也能把每個截屏命令都執行到。
另外,Distinct按鈕可以把Path檔案夾所在的所有檔案檢查一遍,自動刪掉內容完全一樣的檔案。這個很實用吧。
源碼在此:http://files.cnblogs.com/bitzhuwei/bitzhuwei.Clipboard.Winform.zip
release版程式在此:http://files.cnblogs.com/bitzhuwei/bitzhuwei.Clipboard.Winform-release.zip
1. 將剪貼簿內的圖片儲存到檔案
代碼如下。
1: void SaveClipboardImage()
2: {
3: var data = System.Windows.Forms.Clipboard.GetDataObject();
4: var bmap = (Image)(data.GetData(typeof(System.Drawing.Bitmap)));
5: if (bmap != null)
6: {
7: bmap.Save("bitzhuwei.cnblogs.com.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
8: bmap.Dispose();
9: }
10: }
2. 監聽剪貼簿變化的事件
override掉主表單的WndProc事件,這樣就能夠實現若且唯若剪貼簿內容發生變化時執行一次儲存動作了。
override掉在主視窗的WindProc事件 const int WM_DRAWCLIPBOARD = 0x308; const int WM_CHANGECBCHAIN = 0x030D; protected override void WndProc(ref Message m) { if (nextClipboardViewer == null) nextClipboardViewer = (IntPtr)SetClipboardViewer((int)this.Handle); switch (m.Msg) { case WM_CHANGECBCHAIN: if (m.WParam == nextClipboardViewer) { nextClipboardViewer = m.LParam; } else { SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam); } break; case WM_DRAWCLIPBOARD: SaveClipboardImage(); //將WM_DRAWCLIPBOARD 訊息傳遞到下一個觀察鏈中的視窗 SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam); //將WM_DRAWCLIPBOARD 訊息傳遞到下一個觀察鏈中的視窗 break; default: base.WndProc(ref m); break; } }
3. 檔案雷同判別
用檔案流一個位元組一個位元組的判斷即可。大部分不同的檔案,判斷不了多少次就會出現位元組不一樣了,所以我對這個方法的效率還是有信心的。自己也實驗過,對視頻得到的1000多張圖片(全屏的1280*800的圖片),2分鐘就把重複的檔案都刪掉了。
刪掉指定檔案夾下所有內容相同的冗餘檔案 private void DeleteRedundancyFiles(string directory) { var files = (new DirectoryInfo(directory)).GetFiles("*.jpg"); for (int i = 0; i < files.Length; i++) { for (int j = i + 1; j < files.Length; j++) { if (File.Exists(files[i].FullName) && File.Exists(files[j].FullName)) { bool removeJ = IsSameContent(files, i, j); if (removeJ) { try { File.Delete(files[j].FullName); } catch (Exception) { } } } } } } private static bool IsSameContent(FileInfo[] files, int i, int j) { var result = true; using (FileStream fsi = new FileStream(files[i].FullName, FileMode.Open)) { using (FileStream fsj = new FileStream(files[j].FullName, FileMode.Open)) { var counti = 0; var countj = 0; do { const int length = 100; var bytesi = new byte[length]; var bytesj = new byte[length]; counti = fsi.Read(bytesi, 0, length); countj = fsj.Read(bytesj, 0, length); if (counti != countj) { result = false; } else { for (int k = 0; k < counti; k++) { if (bytesi[k] != bytesj[k]) { result = false; break; } } } } while (result && counti > 0 && countj > 0); } } return result; }