亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從Clipboard類獲取圖像格式?

如何從Clipboard類獲取圖像格式?

C#
眼眸繁星 2023-07-22 18:32:38
我正在用 C# 制作一個圖像查看器。該功能是使用 C# 上的 Clipboard 類進行復制和粘貼功能。我成功獲取了BitmapSource的圖像。但它無法檢查圖像格式(jpeg、png、bmp)。這是 C# 支持的源 BitmapSource source = Clipboard.GetImage();這些是我想要使用的。 byte[] image = Clipboard.GetImage("image/png") byte[] image = Clipboard.GetImage("image/bmp")我會說,如何從 BitmapSource 或剪貼板檢查圖像格式?
查看完整描述

1 回答

?
料青山看我應如是

TA貢獻1772條經驗 獲得超8個贊

簡而言之,你不能。

圖像作為原始位圖保存在剪貼板上。有些應用程序也將其以 png 格式顯示,但這并不是為了保留原始格式,而只是為了更好地支持 alpha-transparency。

但是,一般來說,剪貼板根本不包含該圖像的來源或最初的格式的任何指示。您還必須意識到剪貼板上的圖像可能根本就不是文件。這就像假設任何復制的文本都必須是一個帶有文件名的完整文本文件。該圖像可能是直接從某個編輯器復制的,甚至可能是直接的 [PrintScreen] 按鈕屏幕截圖。

然而...

注意到,當我從 Chrome 復制圖像并將其粘貼到 Discord 中時,Discord 會以某種方式知道它在 Chrome 中的文件名。這是因為您可以同時將多種格式的數據放入剪貼板。

該系統通常旨在確保每個應用程序都可以讀取最適合它的內容。例如,對于從網頁復制的內容,記事本將首選純文本版本,而 Microsoft Word 將采用 HTML(如果可用)。同樣,正如我所提到的,應用程序通常以位圖和 png 格式復制圖像,以確保支持透明度的接收應用程序可以采用支持透明度的 PNG 版本,而不了解使用 PNG 的新趨勢的應用程序可以采用經典位圖。

但許多應用程序也使用它來將元數據添加到復制的內容中。當我在 Chrome 中復制您頭像的 32x32 縮略圖時,剪貼板中的內容之一是此文本片段標識為HTML Format

Version:0.9

StartHTML:0000000105

EndHTML:0000000238

StartFragment:0000000141

EndFragment:0000000202

<html>

<body>

<!--StartFragment--><img src="https://i.stack.imgur.com/Eql2x.jpg?s=32&amp;g=1"/><!--EndFragment-->

</body>

</html>

(我相信指定 HTML 片段信息的標頭可能是標準格式。但從未研究過這一點。)

如您所見,這包含文件名,并且您通常會獲得一個擴展名,可用于確定文件的原始格式。

但該文件不再是那種格式。因為,它只是剪貼板上的數據,而不是實際的文件。復制圖像后 Chrome 剪貼板的完整轉儲包含以下格式:

  • System.Drawing.Bitmap(.Net Bitmap 對象。這可能在 WPF 上以不同的方式公開)

  • Bitmap(和System.Drawing.Bitmap我想的一樣)

  • HTML Format(上面顯示的片段)

  • DeviceIndependentBitmap(包含 DIB v1 圖像字節的字節流;在剪貼板上傳輸圖像的最常見方式;經常被濫用為具有 alpha 功能,因為它是 32 位 RGB)

  • Format17(包含 DIB v5 圖像字節的字節流;比 v1 稍微高級,并且正式支持 alpha?!?7”指的是舊 Windows 版本中使用的舊數字剪貼板格式)

如您所見,其中沒有 jpeg 文件。因為當您處于剪貼板級別時,永遠不會假定保留原始文件格式。即使是能夠讀取并保留文件名的 Discord,也會將粘貼的文件另存為 png,并根據需要調整文件擴展名。

在這種特定情況下,您當然可以實際從該 url 下載圖像,而不是使用剪貼板版本。但從技術上講,這永遠不能保證是相同的圖像。

請注意,Chrome 就是這樣做的。無法保證來自其他應用程序甚至其他瀏覽器的剪貼板副本將發送元數據,并且如果發送元數據,則其格式是否略有可比。


我用來分析剪貼板數據的代碼:

(注意,這是 Windows 窗體代碼。我不知道它的 WPF 等效項)

DataObject retrievedData = (DataObject)Clipboard.GetDataObject();

if (retrievedData == null)

? ? return;

String[] formats = retrievedData.GetFormats();

foreach (String format in formats)

{

? ? Object contents = retrievedData.GetData(format);

? ? MemoryStream ms = contents as MemoryStream;

? ? Byte[] bContents = ms == null ? null : ms.ToArray();

? ? String sContents = contents as String;


? ? // Check if bContents and sContents are null here, and analyse their contents


? ? // ...

}


查看完整回答
反對 回復 2023-07-22
  • 1 回答
  • 0 關注
  • 222 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號