65.9K
CodeProject 正在变化。 阅读更多。
Home

提取 .NET 资源的图像和图标

starIconstarIconstarIconstarIconstarIcon

5.00/5 (14投票s)

2011年11月17日

CPOL
viewsIcon

59221

downloadIcon

4890

列出并提取 .NET 资源

Sample Image - maximum width is 600 pixels

引言

本文介绍如何解析和提取 .NET 资源。我们许多人无法找到在项目中使用过的图像和图标。当我们想在另一个项目或使用不同大小的图像时,不得不搜索许多磁盘或网络。在另一种情况下,我们想从我们未开发的程序集中使用图像或图标。

资源类型

使用资源解析器,我们可以列出并提取图标、图像和字符串资源。所有资源项目类都源自 IResourceItem 接口。

#region Properties
string Name { get; set; }
object Value { get; set; }
ResourceType ResourceType { get; }
int BoundHeight { get; }
#endregion

#region Methods
void Save();

void Draw(Graphics graphics, Font font, Rectangle bound);
#endregion

Draw 方法用于在列表中列出项目,Save 方法用于从列表中保存为默认值。

Sample Image - maximum width is 600 pixels

解析资源

为了解析资源,我们首先使用反射获取程序集信息和所选文件的清单资源名称。在解析程序集清单名称后,我们逐个解析所有清单文件。

Assembly assembly = Assembly.LoadFile(fileName);
string[] names = assembly.GetManifestResourceNames();
for (int i = 0; i < names.Length; i++)
{
ManifestResourceInfo info = assembly.GetManifestResourceInfo(names[i]);
	ResourceContainer container = new ResourceContainer(names[i]);
	container.Resolve(assembly, names[i]);
cbResources.Items.Add(container);
}

public void Resolve(Assembly assembly, string name)
{
_Items = new List<IResourceItem>();
	Stream resourceStream = assembly.GetManifestResourceStream(name);
	if (resourceStream == null)
		return;
	ManifestResourceInfo info = assembly.GetManifestResourceInfo(name);
	if (((info.ResourceLocation & ResourceLocation.Embedded) ==
		ResourceLocation.Embedded) && name.EndsWith(".resources"))
		{
			ResourceReader reader = new ResourceReader(resourceStream);
			IDictionaryEnumerator enumerator = reader.GetEnumerator();
			while (enumerator.MoveNext())
			{
				string type = string.Empty;
				string key = enumerator.Key.ToString();
				byte[] values = null;
				reader.GetResourceData(key, out type, out values);
				List<IResourceItem> items =
					ResourceItem.GetResourceItem
					(key, enumerator.Value, resourceStream);
				if (items != null)
				{
					for (int i = 0; i < items.Count; i++)
					{
						Items.Add(items[i]);
					}
				}
			}
		}
	}

我们按类型创建资源项目。

public static List<IResourceItem>
GetResourceItem(string name, object value, Stream stream)
{
	if (value is string)
	{
		StringResourceItem item = new StringResourceItem(name, value);
		return new List<IResourceItem>() { item };
	}
	else if (value is Icon)
	{
		IconResourceItem item = new IconResourceItem(name, value);
		return new List<IResourceItem>() { item };
	}
	else if (value is ImageListStreamer)
	{
		List<IResourceItem> items = new List<IResourceItem>();
		using (ImageList list = new ImageList())
		{
			list.ImageStream = value as ImageListStreamer;
			int index = 0;
			foreach (Image image in list.Images)
			{
				items.Add(new ImageResourceItem(name, image, index));
				index++;
			}
		}
		return items;
	}
	else if (value is Image)
	{
		ImageResourceItem item = new ImageResourceItem(name, value, -1);
		return new List<IResourceItem>() { item };
	}
	else
	{
		object v = value;
	}

	return null;
}

保存图像

单击“保存所有图像”按钮后,资源解析器会将所有图像和图标保存到所选路径。

private void _SaveAllImages()
{
	if (cbResources.Items.Count == 0)
	{
		_LoadResources();
	}
	lblMessage.Text = "Saving...";
	Application.DoEvents();
	using (FolderBrowserDialog dialog = new FolderBrowserDialog())
	{
		if (!string.IsNullOrEmpty(Properties.Settings.Default.DefaultSavePath))
		{
			dialog.SelectedPath =
				Properties.Settings.Default.DefaultSavePath;
		}
		if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
		{
			Properties.Settings.Default.DefaultSavePath =
						dialog.SelectedPath;
			Properties.Settings.Default.Save();
			string iconDirectory = dialog.SelectedPath + "\\Icons";
			string imageDirectory = dialog.SelectedPath + "\\Images";
			if (!Directory.Exists(iconDirectory))
				Directory.CreateDirectory(iconDirectory);
			if (!Directory.Exists(imageDirectory))
				Directory.CreateDirectory(imageDirectory);
			for (int resourceIndex = 0; resourceIndex <
					cbResources.Items.Count; resourceIndex++)
			{
				ResourceContainer container =
				cbResources.Items[resourceIndex] as ResourceContainer;
				string[] names = container.Name.Split
						(new char[] { '.' });

				for (int itemIndex = 0;
				itemIndex < container.Items.Count; itemIndex++)
				{
					IResourceItem item = container.Items
								[itemIndex];
					string fileName = string.Empty;
					if (item.ResourceType == ResourceType.Icon)
					{
						IconResourceItem resourceItem =
							item as IconResourceItem;
						if (resourceItem.Icon != null)
						{
							if (names.Length > 1)
							{
								fileName = dialog.
								SelectedPath +
								"\\Icons\\" +
								names[names.Length
								- 2] + ".ico";
								using (FileStream
								fs = new FileStream
								(fileName,
								FileMode.Create,
								FileAccess.Write))
								{
								    resourceItem.
								    Icon.Save(fs);
								    fs.Flush();
								}
							}
						}
					}
					else if (item.ResourceType ==
							ResourceType.Image)
					{
						ImageResourceItem imageItem =
							item as ImageResourceItem;
						if (imageItem.Image != null)
						{
							string name =
								imageItem.Name;
							if (imageItem.Index != -1)
							{
								name = imageItem.
								Index.ToString();
							}
							fileName = dialog.
							SelectedPath +
							"\\Images\\" +
							names[names.Length - 2] +
							"_" + imageItem.Width.
							ToString() +
							"_" + name + ".png";
							imageItem.Image.Save
							(fileName, ImageFormat.Png);
						}
					}
				}
			}
			MessageBox.Show("Operation Finished", "Success",
				MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
		}
	}
	lblMessage.Visible = false;
}
Sample Image - maximum width is 600 pixels
© . All rights reserved.