Reputation: 1559
i'm developing a ppt add in form of side panel on powerpoint window what i need is customized slide thumbnails, what i've done so far i use Export() method to convert all of slides to temporary images and display them. but this approach is too slow since i need to save/load from disk and my requirement is to display them in an interactive way (need to be fast enough)
i'm wondering if there's a way to export slide thumbnail in the memory...
Upvotes: 0
Views: 2322
Reputation: 1559
thanks for Steve for the idea using clipboard,
EDIT it works but is still slow, when i generate 70 slides it took 4-5 seconds it seems that Copy() method is quite slow so the overhead is not in the bitmap image of clipboard...
here's what I've done
slide.Copy();
if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Bitmap))
{
ImageSource imgSource = BinaryStructConverter.ImageFromClipboardDib();
}
For BinaryStructConverter i got a nice code from here: http://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/ (somehow we need to convert it because if you just copy it directly from clipboard, the bitmap image format is likely to be messed up)
[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);
}
}
}
Upvotes: 0
Reputation: 14809
One possible approach:
ActivePresentation.Slides(x).Copy
That will put the slide on the Windows clipboard in a number of formats, including bitmap, PNG, JPG, etc.
If you have a way of loading the image from the clipboard into whatever you're doing, you're good to go.
Upvotes: 1