.net 接收从网页拖到WPF窗口的图像
我希望我的WPF应用程序成为拖放目标,并且我希望能够从任何网页拖动图像 当从网页拖动图像时,它显然是“DragImageBits”格式,可以反序列化为type。(我是如何定义它的,请参见问题的底部) 如何将其转换为WPF图像 这是我目前的尝试。(如果有人知道实现愿望的正确方法,我洗耳恭听) 此时,我得到一个类型为.net 接收从网页拖到WPF窗口的图像,.net,wpf,winforms,drag-and-drop,bitmap,.net,Wpf,Winforms,Drag And Drop,Bitmap,我希望我的WPF应用程序成为拖放目标,并且我希望能够从任何网页拖动图像 当从网页拖动图像时,它显然是“DragImageBits”格式,可以反序列化为type。(我是如何定义它的,请参见问题的底部) 如何将其转换为WPF图像 这是我目前的尝试。(如果有人知道实现愿望的正确方法,我洗耳恭听) 此时,我得到一个类型为System.Runtime.InteropServices.ExternalException的异常,消息只是Generic GDI+error 有人知道我应该做什么吗 下面是支持类
System.Runtime.InteropServices.ExternalException
的异常,消息只是Generic GDI+error
有人知道我应该做什么吗
下面是支持类的定义。我是从我的书里抄来的
以下是我学到的: “DragImageBits”由windows shell提供,仅用于拖动光标,不用于最终数据。外壳通过调整大小和透明度将图像转换为适当的拖动光标 例如,如果拖动此图像: SHDRAGIMAGE将呈现如下所示: 如果您真的想从SHDRAGIMAGE中提取图像,下面是代码。(部分吊离) 如果要将DragImageBits用于其预期用途(作为拖动图像),请参阅(存档),以获取一个简单的可下载示例
因此,“DragImageBits”实际上是在分散对实际问题的注意力,即接受从网页拖动的图像。 从网页拖动图像会变得复杂,因为Firefox、Chrome和IE9都提供了不同的格式集。此外,您还需要同时处理图像和图像超链接,并且它们的处理方式也会有所不同 Google和Firefox提供了一种“text/html”格式,它将一个html元素作为图像。Google将其作为ASCII字符串提供给您,Firefox将其作为unicode字符串提供给您。下面是我为处理它而编写的代码:
System.Windows.IDataObject data = e.Data;
string[] formats = data.GetFormats();
if (formats.Contains("text/html"))
{
var obj = data.GetData("text/html");
string html = string.Empty;
if (obj is string)
{
html = (string)obj;
}
else if (obj is MemoryStream)
{
MemoryStream ms = (MemoryStream)obj;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
if (buffer[1] == (byte)0) // Detecting unicode
{
html = System.Text.Encoding.Unicode.GetString(buffer);
}
else
{
html = System.Text.Encoding.ASCII.GetString(buffer);
}
}
// Using a regex to parse HTML, but JUST FOR THIS EXAMPLE :-)
var match = new Regex(@"<img[^/]src=""([^""]*)""").Match(html);
if (match.Success)
{
Uri uri = new Uri(match.Groups[1].Value);
SetImageFromUri(uri);
}
}
对于IE9,您可以处理“FileDrop”格式。这在IE9中运行良好。Chrome不支持它。Firefox确实支持它,但会将图像转换为位图,并将透明像素转换为黑色。因此,只有在“text.html”格式不可用时,才应处理“FileDrop”格式
else if (formats.Contains("FileDrop"))
{
var filePaths = (string[])data.GetData("FileDrop");
using (var fileStream = File.OpenRead(filePaths[0]))
{
var buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
this.ImageBinary = buffer;
}
}
如果从IE9拖动图像超链接,则不提供“FileDrop”格式。我还不知道如何将IE9中的图像超链接中的图像拖到我的图像控件上
**额外信息** 如果您正在使用此示例,但仍需要将此二进制数据转换为图像,则以下是一段有用的代码片段:
BitmapImage sourceImage = new BitmapImage();
using (MemoryStream ms = new MemoryStream(imageBinary))
{
sourceImage.BeginInit();
sourceImage.CacheOption = BitmapCacheOption.OnLoad;
sourceImage.StreamSource = ms;
sourceImage.EndInit();
}
我也有同样的问题——我发现Firefox和IE9都提供了设备独立位图(DIB)格式。在这种情况下,不需要使用WebClient下载文件,因为我们可以访问熟悉的(位图)格式的文件。Firefox还公开了“FileDrop”格式,但在解析html和使用FileDrop格式的情况下,可以下载不一定是图像的对象。这对我帮助很大。谢谢你的发帖。正则表达式无法匹配许多有效的图像链接。我发现@“]+src=”“([^”“]*)”的效果更好一些。你真是个救命恩人。如果像我这样的其他人想直接从google images中拖动图像,请检查URI字符串,如果它以
“data”
开头,则这些字符串已经包含数据,不应下载到“this blog”的链接在此处可用:。顺便说一句:有用的问题和答案!
System.Windows.IDataObject data = e.Data;
string[] formats = data.GetFormats();
if (formats.Contains("text/html"))
{
var obj = data.GetData("text/html");
string html = string.Empty;
if (obj is string)
{
html = (string)obj;
}
else if (obj is MemoryStream)
{
MemoryStream ms = (MemoryStream)obj;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, (int)ms.Length);
if (buffer[1] == (byte)0) // Detecting unicode
{
html = System.Text.Encoding.Unicode.GetString(buffer);
}
else
{
html = System.Text.Encoding.ASCII.GetString(buffer);
}
}
// Using a regex to parse HTML, but JUST FOR THIS EXAMPLE :-)
var match = new Regex(@"<img[^/]src=""([^""]*)""").Match(html);
if (match.Success)
{
Uri uri = new Uri(match.Groups[1].Value);
SetImageFromUri(uri);
}
}
private void SetImageFromUri(Uri uri)
{
string fileName = System.IO.Path.GetTempFileName();
using (WebClient webClient = new WebClient())
{
webClient.DownloadFile(uri, fileName);
}
using (FileStream fs = File.OpenRead(fileName))
{
byte[] imageData = new byte[fs.Length];
fs.Read(imageData, 0, (int)fs.Length);
this.ImageBinary = imageData;
}
File.Delete(fileName);
}
else if (formats.Contains("FileDrop"))
{
var filePaths = (string[])data.GetData("FileDrop");
using (var fileStream = File.OpenRead(filePaths[0]))
{
var buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
this.ImageBinary = buffer;
}
}
BitmapImage sourceImage = new BitmapImage();
using (MemoryStream ms = new MemoryStream(imageBinary))
{
sourceImage.BeginInit();
sourceImage.CacheOption = BitmapCacheOption.OnLoad;
sourceImage.StreamSource = ms;
sourceImage.EndInit();
}