BitmapImage加载pack://和c:\ uri之间的差异

时间:2014-10-24 23:13:22

标签: c# icons esri

尝试从文件加载图片而不是pack://

时,我遇到了一个奇怪的错误

我在加速模式下使用ESRI地图,并希望用户能够使用自己的地图图标(将它们复制到Icons目录)。

我已经做了一个图标管理员助手,在程序启动时加载图标:

            public static void Reload()
            {
                _icons = new Dictionary<string, BitmapImage>();

                // read pack://
                var asm = Assembly.GetEntryAssembly();
                var resName = asm.GetName().Name + ".g.resources";
                using (var stream = asm.GetManifestResourceStream(resName))
                    if (stream != null)
                        using (var reader = new System.Resources.ResourceReader(stream))
                        {
                            var regex = new Regex(@"images\/(.+\.png)");
                            foreach (DictionaryEntry entry in reader)
                            {
                                var name = string.Empty;
                                var matched = regex.Match(entry.Key.ToString());
                                if (matched.Groups.Count == 2)
                                {
                                    name = matched.Groups[1].Value;
                                }

                                BitmapImage image = null;
                                try
                                {
                                    image = new BitmapImage();
                                    image.BeginInit();
                                    image.UriSource =
                                        new Uri(@"pack://application:,,,/Client;component/Images/" + matched.Groups[1].Value, UriKind.RelativeOrAbsolute);
                                    image.EndInit();
                                }
                                catch(Exception e)
                                {
                                    Logger.Log(e);
                                    image = null;
                                }

                                if ((name != string.Empty) && (image != null)) 
                                    _icons.Add(@"resource\" + name, image);
                            }
                        }

                // read directory
                var fregex = new Regex(@"\\(.+\.png)$");
                string[] files = null;
                try { files = Directory.GetFiles(Settings.Default.ExternalIconsPath, "*.png", SearchOption.AllDirectories); }
                    catch (Exception e) { Logger.Log(e); }

                if (files != null)
                    foreach (var file in files)
                    {
                        var name = string.Empty;
                        BitmapImage image = null;
                        try
                        {
                            image = new BitmapImage;
                            image.BeginInit();
                            image.UriSource = new Uri(file, UriKind.RelativeOrAbsolute);
                            image.EndInit();

                            var match = fregex.Match(file);
                            if (match.Groups.Count == 2) name = match.Groups[1].Value;
                        }
                        catch (Exception e)
                        {
                            Logger.Log(e); 
                            image = null; 
                        }

                        if ((name == string.Empty) || (image == null)) continue;
                        if (!_icons.ContainsKey(name)) _icons.Add(name, image);
                    }
            }

public static BitmapImage GetImageByName(string name)
        {
            var defaultImage = new BitmapImage(new Uri(@"pack://application:,,,/Client;component/Images/_default_icon_32_32.png", UriKind.RelativeOrAbsolute));
            if ((name == null) || (_icons == null)) return defaultImage;

            BitmapImage image;
            var res = _icons.TryGetValue(name, out image);
            return res ? image : defaultImage;
        }

稍后在代码中我会像这样使用它:

        cameraGraphic.Symbol = new PictureMarkerSymbol
            {
                OffsetX = 12, 
                OffsetY = 12, 
                //Source = IconManager.GetImageByName("resource\\blue_eye_buble2_24_24.png"),
                Source = IconManager.GetImageByName("blue_eye_buble2_24_24.png"),
                Width = 24, 
                Height = 24
            };

它没有任何问题,但是当我设置UseAcceleratedDisplay =&#34; True&#34; (DirectX加速)到ESRI地图图层当我从文件中使用图标时我得到了一个System.NullReferenceException(我试过相同的图标)。 pack://中的图标在加速和非加速模式下都很有效。

有什么区别?我应该使用其他方式从文件加载图标吗?

1 个答案:

答案 0 :(得分:0)

我打败了它。这完全是关于相对和绝对路径。 这很好用:

image.UriSource = new Uri("file:///" + baseDir + file, UriKind.Absolute);