Вопрос по vba – Как сохранить значок ImageMSO из Microsoft Office 2007?

8

Я нашел много хороших иконок из Microsoft Office 2007. У вас есть идеи для Extract & amp; сохранить все значки в формате PNG с помощью VBA?

Неполное изображение MSO

Следующий код является кодом, который используется для получения изображения из 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
@Soul_Master удачи в извлечении? Sergey Mirvoda

Ваш Ответ

4   ответа
7

Я использую ImageMso довольно часто в моей разработке Excel. Наткнувшись на этот пост, я сделал еще один шаг и собрал пакет для визуального поиска, извлечения и сохранения иконок из Microsoft Excel в виде файла или копирования и вставки (с прозрачностью альфа-канала) в другое приложение. Я также составил список из 8 899 различных имен ImageMso из разных источников. Я надеюсь, что другие могут найти это полезным.

Галерея значков Microsoft Office (ImageMSO) & amp; экстракция

ImageMSO Gallery on Microsoft Excel 2013 running Windows 8

Я выпустил обновление с несколькими оптимизациями. Я приложил скриншот галереи, работающей в Microsoft Excel 2013 на Windows 8. Надеюсь, это решит вашу проблему, и если это не так, возможно, я смогу просто получить файлы PNG для вас. В частности, теперь есть 8 899 имен ImageMSO от поиска дополнительного источника.
Я использую 32-разрядную версию Excel 2013. После загрузки этой надстройки ничего не произошло. Soul_Master
Я смог загрузить надстройку в Excel 2013 в Windows 8. Но на вкладке «Вставка» нет новой группы или команды. Soul_Master
Прекрасно работает для меня в Excel 2010 32-разрядной версии на Win7! Спасибо!
К сожалению, он не работает в Excel 2013. Soul_Master
1

Все файлы PNG можно найтиВот Все они уже в формате PNG. Хорошее программирование! (хороший ZIP-архив также доступенВот) 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

0

Я попробовал ответ Исмаила, и он отлично работал. Однако мне потребовалось некоторое время, чтобы понять, как заставить это работать. Я могу поделиться этим немного знания, край:

Решение требует ExcelDna от codeplex:ссылка на сайт.

Как я используюNet 4.0 у меня нет.zip поддержка, поэтому я сначала извлек.xslm файлы в плоскую структуру каталогов, то я изменил код для чтения непосредственно из файлов. Затем в Excel я вызываю метод расширения ExcelDna как

=ExtractIcons("Office2207IconsGallery";"folder_where_to_store_icons")

Использование операторов для служебного класса (для меня):

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

Я обернул класс C # Utility для извлечения значков галереи Office2007 в файлы .png, сохраняя при этом их прозрачность. Основной код взят из отличной статьи Эндрю Уайтчепела ( http://blogs.msdn.com/b/andreww/archive/2007/10/10/preserving-the-alpha-channel-when-converting-images.aspx). Я интегрировал это с образцом списка значков Office 2007 на случай, если вы хотите извлечь все эти значки в целевую папку.

Шаги:

1) Загрузите таблицу Office Gallery по адресуhttp://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11675

2) Вызовите OfficeIcons.ExtractAllIcons () с указанием расположения электронной таблицы Office2007IconsGallery.xlsm и целевой папки, в которую вы хотите извлечь значки.

{код}

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

}

{код}

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы