我正在开发一个 ppt 以在 powerpoint 窗口上以侧面板的形式添加我需要的是自定义幻灯片缩略图,到目前为止我所做的我使用 Export() 方法将所有幻灯片转换为临时图像并显示它们。但这种方法太慢了,因为我需要从磁盘保存/加载,我的要求是以交互方式显示它们(需要足够快)
我想知道是否有办法在内存中导出幻灯片缩略图...
我正在开发一个 ppt 以在 powerpoint 窗口上以侧面板的形式添加我需要的是自定义幻灯片缩略图,到目前为止我所做的我使用 Export() 方法将所有幻灯片转换为临时图像并显示它们。但这种方法太慢了,因为我需要从磁盘保存/加载,我的要求是以交互方式显示它们(需要足够快)
我想知道是否有办法在内存中导出幻灯片缩略图...
一种可能的方法:
ActivePresentation.Slides(x).Copy
这会将幻灯片以多种格式放在 Windows 剪贴板上,包括位图、PNG、JPG 等。
如果您有办法将剪贴板中的图像加载到您正在做的任何事情中,那么您就可以开始了。
感谢史蒂夫使用剪贴板的想法,
编辑 它可以工作但仍然很慢,当我生成 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);
}
}
}