我有一个IntPtr封装在一个与图标句柄相对应的非托管/管理边界上。通过FromHandle()方法将它转换为Icon是微不足道的,直到最近才令人满意。
基本上,我已经有了足够的线程怪异现在MTA / STA跳舞我一直在玩,以保持托管的WinForm打破应用程序的主要(WPF-tastic)UI太脆弱不能坚持。所以WinForm必须走了。
那么,我怎样才能获得Icon的ImageSource版本?
注意,我尝试过ImageSourceConverter无济于事。
顺便说一句,我可以获得某些的底层资源,但不是所有涉及的图标,它们通常存在于我的应用程序的程序集之外(事实上,它们通常存在于非托管的dll中)。
答案 0 :(得分:80)
简单的转换方法,无需创建任何额外的对象:
public static ImageSource ToImageSource(this Icon icon)
{
ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
icon.Handle,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
return imageSource;
}
答案 1 :(得分:51)
试试这个:
Icon img;
Bitmap bitmap = img.ToBitmap();
IntPtr hBitmap = bitmap.GetHbitmap();
ImageSource wpfBitmap =
Imaging.CreateBitmapSourceFromHBitmap(
hBitmap, IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
更新:纳入Alex的建议并将其作为扩展方法:
internal static class IconUtilities
{
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
public static ImageSource ToImageSource(this Icon icon)
{
Bitmap bitmap = icon.ToBitmap();
IntPtr hBitmap = bitmap.GetHbitmap();
ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
if (!DeleteObject(hBitmap))
{
throw new Win32Exception();
}
return wpfBitmap;
}
}
然后你可以这样做:
ImageSource wpfBitmap = img.ToImageSource();
答案 2 :(得分:10)
使用一次性流时,几乎总是建议使用“使用”块来强制正确释放资源。
using (MemoryStream iconStream = new MemoryStream())
{
icon.Save(iconStream);
iconStream.Seek(0, SeekOrigin.Begin);
this.TargetWindow.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconStream);
}
其中
icon
是源System.Drawing.Icon,this.TargetWindow
是目标System.Windows.Window。
答案 3 :(得分:9)
MemoryStream iconStream = new MemoryStream();
myForm.Icon.Save(iconStream);
iconStream.Seek(0, SeekOrigin.Begin);
_wpfForm.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconStream);
答案 4 :(得分:1)
从上面的一些方面来看,这为我自己创造了最高质量的图标。从字节数组加载图标。我使用缓存onload,因为如果你不这样做,你将在处理内存流时得到一个处理异常。
internal static ImageSource ToImageSource(this byte[] iconBytes)
{
if (iconBytes == null)
throw new ArgumentNullException(nameof(iconBytes));
using (var ms = new MemoryStream(iconBytes))
{
return BitmapFrame.Create(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
}
}
答案 5 :(得分:0)
以某种方式类似的例子,仅从开发人员的用例...
调整 JavaReceiverInputDStream<String> streamData1 = ssc.socketTextStream("localhost",996,
StorageLevels.MEMORY_AND_DISK_SER);
JavaReceiverInputDStream<String> streamData2 = ssc.socketTextStream("localhost", 9995,StorageLevels.MEMORY_AND_DISK_SER);
JavaPairDStream<Integer, String> dataStream1= streamData1.mapToPair(new PairFunction<String, Integer, String>() {
public Tuple2<Integer, String> call(String stream) throws Exception {
Tuple2<Integer,String> streamPair= new Tuple2<Integer, String>(1, stream);
return streamPair;
}
});
JavaPairDStream<Integer, String> dataStream2= streamData2.mapToPair(new PairFunction<String, Integer, String>() {
public Tuple2<Integer, String> call(String stream) throws Exception {
Tuple2<Integer,String> streamPair= new Tuple2<Integer, String>(2, stream);
return streamPair;
}
});
dataStream2.print(); //for example
答案 6 :(得分:-2)
这个问题有一个非常简单的解决方案。
步骤:
(1)将图像添加到解决方案资源管理器中的资源 - &gt; resources.resx (2)编辑里面的图像属性&#34;资源&#34;解决方案资源管理器中的目录并更改&#34;构建操作&#34;到&#34;资源&#34;
在xaml中,添加以下内容......
Icon =&#34;资源/图片名称&#34; (其中&#34;图像名称&#34;是您添加到资源的图像的名称 - 请参阅第(1)点。