0

我正在开发一个 ppt 以在 powerpoint 窗口上以侧面板的形式添加我需要的是自定义幻灯片缩略图,到目前为止我所做的我使用 Export() 方法将所有幻灯片转换为临时图像并显示它们。但这种方法太慢了,因为我需要从磁盘保存/加载,我的要求是以交互方式显示它们(需要足够快)

我想知道是否有办法在内存中导出幻灯片缩略图...

4

2 回答 2

1

一种可能的方法:

ActivePresentation.Slides(x).Copy

这会将幻灯片以多种格式放在 Windows 剪贴板上,包括位图、PNG、JPG 等。

如果您有办法将剪贴板中的图像加载到您正在做的任何事情中,那么您就可以开始了。

于 2013-01-24T15:59:48.040 回答
0

感谢史蒂夫使用剪贴板的想法,

编辑 它可以工作但仍然很慢,当我生成 70 张幻灯片时需要 4-5 秒,看来 Copy() 方法很慢,所以开销不在剪贴板的位图图像中......

这就是我所做的

slide.Copy();
if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Bitmap))
{
    ImageSource imgSource = BinaryStructConverter.ImageFromClipboardDib();
}

对于 BinaryStructConverter 我从这里得到了一个很好的代码: http ://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/ (我们需要以某种方式转换它,因为如果你直接从剪贴板复制就行了,位图图片格式很可能乱码)

[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct BITMAPFILEHEADER
{
    public static readonly short BM = 0x4d42; // BM

    public short bfType;
    public int bfSize;
    public short bfReserved1;
    public short bfReserved2;
    public int bfOffBits;
}

[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
    public int biSize;
    public int biWidth;
    public int biHeight;
    public short biPlanes;
    public short biBitCount;
    public int biCompression;
    public int biSizeImage;
    public int biXPelsPerMeter;
    public int biYPelsPerMeter;
    public int biClrUsed;
    public int biClrImportant;
}

public static class BinaryStructConverter
{
    public static ImageSource ImageFromClipboardDib()
    {
        MemoryStream ms = Clipboard.GetData("DeviceIndependentBitmap") as MemoryStream;
        if (ms != null)
        {
            byte[] dibBuffer = new byte[ms.Length];
            ms.Read(dibBuffer, 0, dibBuffer.Length);

            BITMAPINFOHEADER infoHeader =
                BinaryStructConverter.FromByteArray<BITMAPINFOHEADER>(dibBuffer);

            int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
            int infoHeaderSize = infoHeader.biSize;
            int fileSize = fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage;

            BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER();
            fileHeader.bfType = BITMAPFILEHEADER.BM;
            fileHeader.bfSize = fileSize;
            fileHeader.bfReserved1 = 0;
            fileHeader.bfReserved2 = 0;
            fileHeader.bfOffBits = fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4;

            byte[] fileHeaderBytes =
                BinaryStructConverter.ToByteArray<BITMAPFILEHEADER>(fileHeader);

            MemoryStream msBitmap = new MemoryStream();
            msBitmap.Write(fileHeaderBytes, 0, fileHeaderSize);
            msBitmap.Write(dibBuffer, 0, dibBuffer.Length);
            msBitmap.Seek(0, SeekOrigin.Begin);

            return BitmapFrame.Create(msBitmap);
        }
        return null;
    }

    public static T FromByteArray<T>(byte[] bytes) where T : struct
    {
        IntPtr ptr = IntPtr.Zero;
        try
        {
            int size = Marshal.SizeOf(typeof(T));
            ptr = Marshal.AllocHGlobal(size);
            Marshal.Copy(bytes, 0, ptr, size);
            object obj = Marshal.PtrToStructure(ptr, typeof(T));
            return (T)obj;
        }
        finally
        {
            if (ptr != IntPtr.Zero)
                Marshal.FreeHGlobal(ptr);
        }
    }

    public static byte[] ToByteArray<T>(T obj) where T : struct
    {
        IntPtr ptr = IntPtr.Zero;
        try
        {
            int size = Marshal.SizeOf(typeof(T));
            ptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(obj, ptr, true);
            byte[] bytes = new byte[size];
            Marshal.Copy(ptr, bytes, 0, size);
            return bytes;
        }
        finally
        {
            if (ptr != IntPtr.Zero)
                Marshal.FreeHGlobal(ptr);
        }
    }
}
于 2013-01-29T07:52:47.290 回答