原文地址 https://www.cnblogs.com/younShieh/p/17010572.html
❤如果本文對你有所幫助,不妨點個關注和推薦呀,這是對筆者最大的支援~❤
我們先考慮一般會從什麼地方複製文字、圖片到我們的軟體中。
首先說文字。我們可能會從文字檔案,網頁,word,ppt,qq,微信,甚至是vsCode等等地方進行復制。能進行文字複製的地方千奇百怪,但是他們使用的都是通用文字容器控制元件(TextBlock、TextBox等),這些控制元件的底層複製操作都是一樣的,都是將字串放置到剪下板中。我們只需要獲取剪下板中的資料就可以獲取到想要的文字資料。當然,如果需要獲取特殊樣式的文字,比如加粗效果、斜體等效果的文字,還需要特殊處理。
注意,如果複製PPT元素時,只是框選中了文字進行復制的話,是可以進行文字貼上的。但是如果複製的是PPT整個文字框元素,就不行。PPT會提前把這個元素轉換為對應圖片儲存到剪下板中。你想去獲取文字時,文字為空,這個元素只能轉換為圖片,甚至預設還有白色背景。。。如果能對PPT進行元素級的解析,則可以轉換為文字。WPS同理。
其次是圖片。能進行圖片複製的地方就沒那麼多了,我們主要考慮常見的地方,比如電腦本機,網頁,ppt,qq,微信等。不同的地方複製的圖片在剪下板中的儲存方式也可能不同,這就需要不同的處理方式。大致可以區分為源文字複製和點陣圖資料複製。
- 獲取剪下板物件
IDataObject dataObject = Clipboard.GetDataObject();
- 分析剪下板資料
透過GetFormats()方法獲取複製元素的型別。
string[] formats = dataObject.GetFormats();
formats陣列中可以看到現在複製的是什麼型別的元素,方便除錯。
解析為純文字。
var str = dataObject.GetData(DataFormats.Text);
複製項不為文字的話,str=null。
本地檔案、qq和微信(部分)中的圖片複製時,為原始檔複製。
if (dataObject.GetFormats().Contains(DataFormats.FileDrop)
&& dataObject.TryGetData(DataFormats.FileDrop) is string[] array
&& array.Any())
{
//array為檔案路徑
}
ppt、word、excel、微信(部分)、網頁中的圖片都儲存為了點陣圖資料,需要按照不同的資料結構進行解析。
可以先建立一個儲存的目錄,把轉換出來的圖片儲存為本地檔案再插入。
圖片可能會有透明圖層,最好轉換為png格式。一般情況下可以直接呼叫GetImage()方法獲取圖片。
特殊的,DIB格式需要單獨處理,某些截圖軟體使用的是這個格式進行儲存。
ppt中有透明圖層的圖片複製出來有白色背景,可以使用InteropBitmap型別進行渲染。
程式碼如下:
string fullName = Path.Combine(AppPath.Temp, Guid.NewGuid().ToString() + ".png");
string[] formats = dataObject.GetFormats();
if (formats.Contains(DataFormats.Dib))
{
if (dataObject.GetData(DataFormats.Bitmap) is Bitmap bitmap)
{
bitmap.Save(fullName, ImageFormat.Png);
}
}
if (!File.Exists(fullName))
{
if (System.Windows.Clipboard.GetData(DataFormats.Bitmap) is InteropBitmap interopBitmap)
{
interopBitmap.ToLocalImage(fullName);
}
else
{
if (System.Windows.Forms.Clipboard.GetImage() is Image image)
{
((Bitmap)image).ToLocalImage(fullName, ImageFormat.Png);
}
}
}
if (File.Exists(fullName))
{
//插入到軟體
}
或許我們還需要在軟體內部對某個特殊元素進行復制貼上。只需要在複製時帶上你的特殊元素型別。
IDataObject dataObject = Clipboard.GetDataObject();
dataObject.SetData(typeof(SpacialElement), _element);
Clipboard.SetDataObject(dataObject, true);
在貼上時,檢查是否存在改型別,或者強制轉換為相應型別。
if(dataObject.GetData(typeof(SpacialElement) is SpacialElement element)
{
}