将URI打包到resx文件中嵌入的图像 [英] Pack URI to image embedded in a resx file

查看:105
本文介绍了将URI打包到resx文件中嵌入的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何为资源文件中的图像构建包URI?

How do I construct a pack URI to an image that is in a resource file?

我有一个名为 MyAssembly.Resources的程序集。 dll ,它有一个名为 Images 的文件夹,然后有一个名为 Assets.resx 的资源文件。此资源文件包含我的图像(称为 MyImage.png )。我的代码行是:

I have an assembly called MyAssembly.Resources.dll, it has a folder called Images, then in there is a resource file called Assets.resx. This resource file contains my image (called MyImage.png). The line of code I have is:

uri = new Uri("pack://application:,,,/MyAssembly.Resources,Culture=neutral,PublicKeyToken=null;component/Images/Assets/MyImage.png");

然而,当我尝试将此URI提供给新的BitmapImage 我得到一个 IOException

However when I try to supply this URI to the constructor of a new BitmapImage I get an IOException with the message


无法找到资源'图像/assets/myimage.png'。

Cannot locate resource 'images/assets/myimage.png'.

请注意,我在同一个程序集中有其他松散图像,我可以使用一个包检索URI,这些图像的构建操作设置为资源但它们未嵌入到resx文件中。我应该在路径中包含resx文件的名称吗?

Note that I have other loose images in the same assembly which I can retrieve fine using a pack URI, those images have their build action set to Resource but they are not embedded in a resx file. Should I be including the name of the resx file in the path?

(我希望在resx文件中嵌入图像,以便我可以利用UI文化设置来检索右图像(图像包含文本))。

(I am looking to embed images in resx files so that I can leverage UI culture settings to retrieve the right image (the image contains text)).

推荐答案

我认为不可能使用pack协议方案。此协议与规范化的开放式打包约定规范相关( http: //tools.ietf.org/id/draft-shur-pack-uri-scheme-05.txt 指针)。因此,包uri指向应用程序包的资源(或OPC术语中的部分),而不是.NET嵌入资源。

I don't think it's possible using the "pack" protocol scheme. This protocol is related to normalized Open Packaging Conventions specs (http://tools.ietf.org/id/draft-shur-pack-uri-scheme-05.txt for pointers). So the pack uri points to the application package's resources (or parts in OPC terms), not to .NET embedded resources.

但是,您可以定义自己的方案,示例resx并在WPF组件uris中使用它。可以使用 WebRequest.RegisterPrefix 定义此类用法的新Uri方案。 。

However, you can define your own scheme, for example "resx" and use it in WPF component uris. New Uri schemes for such usages can be defined using WebRequest.RegisterPrefix.

这是一个基于名为WpfApplication1的小型Wpf应用程序项目的示例。此应用程序定义了Resource1.resx文件(可能还有其他本地化的相应Resource1文件,例如法语的Resource1.fr-FR.resx)。这些ResX文件中的每一个都定义了一个名为img的Image资源(请注意,此名称与资源所基于的图像文件名不同)。

Here is an example based on a small Wpf application project named "WpfApplication1". This application has a Resource1.resx file defined (and possibly other localized corresponding Resource1 files, like Resource1.fr-FR.resx for french for example). Each of these ResX files define an Image resource named "img" (note this name is not the same as the image file name the resource is based on).

这是MainWindow.xaml:

Here is the MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Image Source="resx:///WpfApplication1.Resource1/img" />
</Window>

uri格式为:

resx://assembly name/resource set name/resource name

和程序集名称是可选的,所以

and assembly name is optional, so

resx:///resource set name/resource name

也有效并指向主程序集中的资源(我的样本使用此内容)

is also valid and point to resources in the main assembly (my sample uses this)

这是支持它的代码,在App.xaml.cs或其他地方,你需要注册新方案:

This is the code that supports it, in App.xaml.cs or somewhere else, you need to register the new scheme:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        ResXWebRequestFactory.Register();
        base.OnStartup(e);
    }
}

计划实施:

public sealed class ResXWebRequestFactory : IWebRequestCreate
{
    public const string Scheme = "resx";
    private static ResXWebRequestFactory _factory = new ResXWebRequestFactory();

    private ResXWebRequestFactory()
    {
    }

    // call this before anything else
    public static void Register()
    {
        WebRequest.RegisterPrefix(Scheme, _factory);
    }

    WebRequest IWebRequestCreate.Create(Uri uri)
    {
        return new ResXWebRequest(uri);
    }

    private class ResXWebRequest : WebRequest
    {
        public ResXWebRequest(Uri uri)
        {
            Uri = uri;
        }

        public Uri Uri { get; set; }

        public override WebResponse GetResponse()
        {
            return new ResXWebResponse(Uri);
        }
    }

    private class ResXWebResponse : WebResponse
    {
        public ResXWebResponse(Uri uri)
        {
            Uri = uri;
        }

        public Uri Uri { get; set; }

        public override Stream GetResponseStream()
        {
            Assembly asm;
            if (string.IsNullOrEmpty(Uri.Host))
            {
                asm = Assembly.GetEntryAssembly();
            }
            else
            {
                asm = Assembly.Load(Uri.Host);
            }

            int filePos = Uri.LocalPath.LastIndexOf('/');
            string baseName = Uri.LocalPath.Substring(1, filePos - 1);
            string name = Uri.LocalPath.Substring(filePos + 1);

            ResourceManager rm = new ResourceManager(baseName, asm);
            object obj = rm.GetObject(name);

            Stream stream = obj as Stream;
            if (stream != null)
                return stream;

            Bitmap bmp = obj as Bitmap; // System.Drawing.Bitmap
            if (bmp != null)
            {
                stream = new MemoryStream();
                bmp.Save(stream, bmp.RawFormat);
                bmp.Dispose();
                stream.Position = 0;
                return stream;
            }

            // TODO: add other formats
            return null;
        }
    }
}

这篇关于将URI打包到resx文件中嵌入的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆