如何从 Microsoft Office 2007 中保存 ImageMSO 图标?
Posted
技术标签:
【中文标题】如何从 Microsoft Office 2007 中保存 ImageMSO 图标?【英文标题】:How to save ImageMSO icon from Microsoft Office 2007? 【发布时间】:2010-11-07 13:59:10 【问题描述】:我从 Microsoft Office 2007 中找到了很多不错的图标。您知道使用 VBA 将所有图标提取并保存为 PNG 文件吗?
Partial ImageMSO http://rabu4g.bay.livefilestore.com/y1p2SF1q63YjDjPNmK4nYMW2644r9AO2aAsE__vBYznTeXD0b4SJUU0O07fxPD0r7aO_83gCJ-8OfcOQsFKG0fQMRnTEneBU1TI/Capture.PNG
以下代码是用于从 ImageMSO 获取图像的代码。
Application.CommandBars.GetImageMso([name], [width], [height])
我可以将所有内容显示为 PictureBox 控件并将 excel 文件保存为网页。但是,每个图标的质量都很低。
此外,我尝试使用以下代码创建用于导出为位图对象的 C# Excel 插件项目。但是我发现它不能导出为半透明的PNG。
stdole.IPictureDisp p = Application.CommandBars.GetImageMso(fileName, size, size);
Bitmap b = Bitmap.FromHbitmap((IntPtr)p.Handle, (IntPtr)p.hPal);
PS。我想将所有图标保存为 PNG 格式,因为我需要使用它的半透明功能。它允许我在大多数背景颜色上使用所有图标而不是白色背景。
【问题讨论】:
@Soul_Master 提取成功了吗? 不。我只是放弃了。 【参考方案1】:所有的PNG文件都可以在here找到这些都是PNG格式的。好编程! (还提供了一个不错的 ZIP 存档Here)ZIP 存档包含所有 17 个 Excel 图标。
当您使用 GetImageMso 方法时,您最终会得到对象的 IPicture 接口。 IPicture 界面访问适合以原始格式保存到文件的图标 - .ICO、.WMF 或 .BMP 不支持 PNG 格式。以下链接解释了为什么这不能直接实现:
http://msdn.microsoft.com/en-us/library/aa434604.aspx(msoGetImageMso 方法) http://msdn.microsoft.com/en-us/library/ms680761%28VS.85%29.aspx(IP图片接口) http://msdn.microsoft.com/en-us/library/ms694504%28VS.85%29.aspx(另存为文件方法)
但是,使用更复杂的方法会产生您想要的结果:
http://blogs.msdn.com/mshneer/archive/2007/10/10/preserving-transparency-when-rendering-office-icons.aspx
【讨论】:
【参考方案2】:我已经封装了一个 C# 实用程序类,用于将 Office2007 画廊图标提取到 .png 文件,同时正确地保持它们的透明度。主要代码取自 Andrew Whitechapel 写的一篇很棒的文章( http://blogs.msdn.com/b/andreww/archive/2007/10/10/preserving-the-alpha-channel-when-converting-images.aspx)。我已将它与 Office 2007 示例图标表集成,以防您要将所有这些图标提取到目标文件夹。
步骤是:
1) 在http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11675下载Office Gallery 电子表格
2) 使用 Office2007IconsGallery.xlsm 示例电子表格的位置以及您想要提取图标的目标文件夹调用 OfficeIcons.ExtractAllIcons()。
代码
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using ExcelDna.Integration;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.Office.Interop.Excel;
using stdole;
public class OfficeIconUtils
public static void ExtractAllIcons(string xlsmPath, string targetFolder)
// extract customUI.xml
var zf = new ZipFile(xlsmPath);
var entry = zf.GetEntry("customUI/customUI.xml");
var zipStream = zf.GetInputStream(entry);
XNamespace ns = "http://schemas.microsoft.com/office/2006/01/customui";
var root = XElement.Load(zipStream);
foreach (var gallery in root.Descendants(ns + "gallery"))
//create a sub-folder for the gallery
var subFolder = Path.Combine(targetFolder,
gallery.Attribute("label").Value);
var width = int.Parse(gallery.Attribute("itemWidth").Value);
var height = int.Parse(gallery.Attribute("itemHeight").Value);
Directory.CreateDirectory(subFolder);
foreach (var item in gallery.Descendants(ns + "item"))
SaveIcon(item.Attribute("imageMso").Value,
subFolder, width, height);
public static void SaveIcon(string msoName, string folder,
int width = 32, int height = 32)
ConvertPixelByPixel(
((Application)(ExcelDnaUtil.Application))
.CommandBars.GetImageMso(msoName, width, height))
.Save(Path.Combine(folder, string.Format("0.png",
msoName)), ImageFormat.Png);
public static Bitmap ConvertPixelByPixel(IPictureDisp ipd)
// get the info about the HBITMAP inside the IPictureDisp
var dibsection = new DIBSECTION();
GetObjectDIBSection((IntPtr)ipd.Handle, Marshal.SizeOf(dibsection), ref dibsection);
var width = dibsection.dsBm.bmWidth;
var height = dibsection.dsBm.bmHeight;
// create the destination Bitmap object
var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
unsafe
// get a pointer to the raw bits
var pBits = (RGBQUAD*)(void*)dibsection.dsBm.bmBits;
// copy each pixel manually
for (var x = 0; x < dibsection.dsBmih.biWidth; x++)
for (var y = 0; y < dibsection.dsBmih.biHeight; y++)
var offset = y * dibsection.dsBmih.biWidth + x;
if (pBits[offset].rgbReserved != 0)
bitmap.SetPixel(x, y, Color.FromArgb(pBits[offset].rgbReserved, pBits[offset].rgbRed, pBits[offset].rgbGreen, pBits[offset].rgbBlue));
return bitmap;
[StructLayout(LayoutKind.Sequential)]
private struct RGBQUAD
public byte rgbBlue;
public byte rgbGreen;
public byte rgbRed;
public byte rgbReserved;
[StructLayout(LayoutKind.Sequential)]
public struct BITMAP
public Int32 bmType;
public Int32 bmWidth;
public Int32 bmHeight;
public Int32 bmWidthBytes;
public Int16 bmPlanes;
public Int16 bmBitsPixel;
public IntPtr bmBits;
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
public int biSize;
public int biWidth;
public int biHeight;
public Int16 biPlanes;
public Int16 biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int bitClrImportant;
[StructLayout(LayoutKind.Sequential)]
public struct DIBSECTION
public BITMAP dsBm;
public BITMAPINFOHEADER dsBmih;
public int dsBitField1;
public int dsBitField2;
public int dsBitField3;
public IntPtr dshSection;
public int dsOffset;
[DllImport("gdi32.dll", EntryPoint = "GetObject")]
public static extern int GetObjectDIBSection(IntPtr hObject, int nCount, ref DIBSECTION lpObject);
代码
【讨论】:
如果您指定了它所依赖的 500 个依赖项,那就太好了,更不用说一旦找到它们,所有代码都无法编译。 添加了参考,对此感到抱歉。它肯定可以编译 -【参考方案3】:我已经尝试过 Ismail 的回答,效果很好。然而,我花了一段时间才弄清楚如何让它工作。我可能会分享这点知识:
该解决方案需要来自 codeplex 的 ExcelDna:link。
由于我使用的是Net 4.0
,我没有 .zip 支持,所以我首先将 .xslm 文件解压缩到一个平面目录结构,然后我将代码更改为直接从文件中读取。
然后在 Excel 中,我将 ExcelDna 扩展方法称为
=ExtractIcons("Office2207IconsGallery";"folder_where_to_store_icons")
实用程序类的 using 语句(对我而言):
using System.Xml.Linq;
using System.IO;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using Application = Microsoft.Office.Interop.Excel.Application;
using ExcelDna.Integration;
using stdole;
希望这会有所帮助....谢谢伊斯梅尔!
【讨论】:
【参考方案4】:我在 Excel 开发中经常使用 ImageMso。偶然发现这篇文章后,我更进一步,将一个包放在一起,以直观地搜索、提取和保存 Microsoft Excel 中的图标作为文件或复制和粘贴(具有 alpha 通道透明度)到另一个应用程序。我还从各种来源编制了一份包含 8,899 个不同 ImageMso 名称的列表。我希望其他人会发现这很有用。
Microsoft Office Icons (ImageMSO) Gallery & Extraction
【讨论】:
我能够在 Windows 8 上将加载项加载到我的 Excel 2013。但“插入”选项卡中没有新的组/命令。 我使用的是 32 位版本的 Excel 2013。加载此插件后没有任何反应。 在 Win7 上的 Excel 2010 32 位中非常适合我!谢谢! 我发布了一个包含多项优化的更新。我附上了在 Windows 8 上在 Microsoft Excel 2013 中运行的画廊的屏幕截图。我希望这可以解决您的问题,如果没有,也许我可以为您获取 PNG 文件。最值得注意的是,现在有 8,899 个 ImageMSO 名称来自寻找其他来源。 不确定我是不是盲人,但我看不到你从哪里下载插件。该站点仅包含带有源代码的“存档”。以上是关于如何从 Microsoft Office 2007 中保存 ImageMSO 图标?的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft Office Communicator Automation API 2007 和接收即时消息
microsoft office Enterprise 2007在安装过程中出错怎么办?
Microsoft office Enterprise 2007安装错误。。这怎么办???
怎么对Microsoft (Office) Word Document 2007 索引化?