2009-07-02 41 views
8

我发现了许多来自Microsoft Office 2007的漂亮图标。你有没有想法提取&使用VBA将所有图标保存为PNG文件?如何从Microsoft Office 2007保存ImageMSO图标?

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格式,因为我需要使用它的半透明功能。它允许我使用大多数背景色的所有图标而不是白色背景。

+0

@Soul_Master与提取任何运气? – 2010-02-24 13:19:24

+0

不是。我只是放弃这个。 – 2010-02-24 18:49:16

回答

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(IPICTURE接口) 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

4

我已经结束了一个C#实用工具类提取的Office2007画廊图标.png文件,同时保持透明度prope RLY。主要代码摘自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

2下载Office库电子表格)与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); 

} 

{}代码

+0

如果您指定了依赖关系的500个依赖项,那就更好了,更不用说一旦找到它们,所有代码都不会编译。 – 2014-06-16 05:43:42

0

我已经试过伊斯梅尔的答案和它的工作很大。然而,我花了一段时间才弄清楚如何使它工作。我可能会分享这一点的知识:

该解决方案需要来自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; 

希望这有助于....谢谢伊斯梅尔!

7

我在我的Excel开发中经常使用ImageMso。在这篇文章中我偶然发现了一些东西,并将它们放在一起,以直观地搜索,提取并保存Microsoft Excel中的图标作为文件,或者复制并粘贴(使用Alpha通道透明)到另一个应用程序。我还编制了来自各种来源的8,899个不同的ImageMso名称列表。我希望别人能找到这个有用的。

Microsoft Office Icons (ImageMSO) Gallery & Extraction

ImageMSO Gallery on Microsoft Excel 2013 running Windows 8

相关问题