2009-07-02 52 views
8

Encontré muchos iconos bonitos de Microsoft Office 2007. ¿Alguna idea para extraer & guardar todos los iconos como archivos PNG utilizando VBA?Cómo guardar el icono ImageMSO de Microsoft Office 2007?

Partial ImageMSO http://rabu4g.bay.livefilestore.com/y1p2SF1q63YjDjPNmK4nYMW2644r9AO2aAsE__vBYznTeXD0b4SJUU0O07fxPD0r7aO_83gCJ-8OfcOQsFKG0fQMRnTEneBU1TI/Capture.PNG

El siguiente código es un código que se utiliza para obtener la imagen de imageMso.

Application.CommandBars.GetImageMso([name], [width], [height]) 

puedo mostrar todos como el control de cuadro de imagen y guardar archivo como página Web de Excel. Sin embargo, cada ícono es de muy baja calidad.

Además, trato de crear un proyecto de complemento Excel de C# para exportarlo como objeto Bitmap utilizando el siguiente código. Pero descubrí que no puede exportar como PNG semitransparente.

stdole.IPictureDisp p = Application.CommandBars.GetImageMso(fileName, size, size); 
Bitmap b = Bitmap.FromHbitmap((IntPtr)p.Handle, (IntPtr)p.hPal); 

PS. Quiero guardar todos los iconos como formato PNG porque necesito usar una característica semitransparente. Me permite usar todos los iconos en la mayoría de los colores de fondo más que en el fondo blanco.

+0

@Soul_Master con un poco de suerte que extrae? –

+0

No. Solo me rindo por esto –

Respuesta

1

Todos los archivos PNG se pueden encontrar here Estos ya están en formato PNG. Buena programación! (También está disponible un buen archivo ZIP Here) El archivo ZIP contiene los 17 iconos de Excel.

Cuando utiliza el método GetImageMso, termina con una interfaz IPicture para el objeto. La interfaz IPicture accede al icono adecuado para guardar en un archivo en el formato original: .ICO, .WMF o .BMP. El formato PNG no es compatible. Los siguientes enlaces explican por qué esto no es posible sin más:

http://msdn.microsoft.com/en-us/library/aa434604.aspx (método msoGetImageMso) http://msdn.microsoft.com/en-us/library/ms680761%28VS.85%29.aspx (IPicture Interface) http://msdn.microsoft.com/en-us/library/ms694504%28VS.85%29.aspx (Guardar como método de archivo)

Sin embargo, el uso de un enfoque más complejo producirá lo que quiere :

http://blogs.msdn.com/mshneer/archive/2007/10/10/preserving-transparency-when-rendering-office-icons.aspx

4

he envuelto una clase C# Utilidad para extraer Office2007 galería iconos para archivos .png, manteniendo su transparencia prope rly. El código principal está tomado de un gran artículo escrito por Andrew Whitechapel ( http://blogs.msdn.com/b/andreww/archive/2007/10/10/preserving-the-alpha-channel-when-converting-images.aspx). He integrado esto con la hoja de iconos de ejemplo de Office 2007, en caso de que quiera extraer todos estos iconos a una carpeta de destino.

Los pasos son:

1) Descargar la hoja de cálculo Galería de oficinas en la http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11675

2) Llame OfficeIcons.ExtractAllIcons() con la ubicación de la hoja de cálculo muestra Office2007IconsGallery.xlsm, y la carpeta de destino en la que desea los íconos extraídos

{code}

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); 

} 

{code}

+0

Sería bueno si especificara las 500 dependencias en las que esto se basa, sin mencionar que una vez que las encuentra, todo el código no se compila. –

+0

Referencias agregadas, perdón por eso. Sin embargo, compila definitivamente: –

0

He tratado de respuesta de Ismail y se hizo un gran trabajo. Sin embargo, me tomó un tiempo encontrar la manera de hacerlo funcionar.Puedo compartir este poco de conocimiento:

La solución requiere ExcelDna de codeplex: link.

Como estoy usando Net 4.0 no tengo .zip apoyo así que primero extrae los .xslm archivos en una estructura de directorios plana entonces he cambiado el código para leer directamente de los archivos. Luego, en el Excel que llamo el método de extensión ExcelDna como

=ExtractIcons("Office2207IconsGallery";"folder_where_to_store_icons") 

las instrucciones using para la clase de utilidad (para mí):

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; 

Esperanza esto ayuda .... Gracias Ismail!

7

Uso ImageMso con bastante frecuencia en mi desarrollo de Excel. Habiendo tropezado con esta publicación, di un paso más y reuní un paquete para buscar visualmente, extraer y guardar iconos de Microsoft Excel como un archivo o copiar y pegar (con transparencia de canal alfa) en otra aplicación. También compilé una lista de 8.899 nombres distintos de ImageMso de varias fuentes. Espero que otros puedan encontrar esto útil.

Microsoft Office Icons (ImageMSO) Gallery & Extraction

ImageMSO Gallery on Microsoft Excel 2013 running Windows 8

+0

Lamentablemente, no funciona en Excel 2013. –

+0

Puedo cargar el complemento en mi Excel 2013 en Windows 8. Pero no hay un nuevo grupo/comando en la pestaña Insertar. –

+0

Uso la versión de 32 bits de Excel 2013. No ocurre nada después de cargar este complemento. –

Cuestiones relacionadas