public static BitmapSource Render(this PdfDocument doc, int page, double factor, bool fixDpi = true) { var size = doc.PageSizes[page]; var scale = DpiHelper.GetCurrentScaleFactor(); var dpiX = fixDpi ? scale.Horizontal * DpiHelper.DefaultDpi : 96; var dpiY = fixDpi ? scale.Vertical * DpiHelper.DefaultDpi : 96; var realWidth = (int)Math.Round(size.Width * scale.Horizontal * factor); var realHeight = (int)Math.Round(size.Height * scale.Vertical * factor); var bitmap = doc.Render(page, realWidth, realHeight, dpiX, dpiY, PdfRenderFlags.LimitImageCacheSize | PdfRenderFlags.LcdText | PdfRenderFlags.Annotations | PdfRenderFlags.ForPrinting) as Bitmap; var bs = bitmap?.ToBitmapSource(); bitmap?.Dispose(); bs?.Freeze(); return(bs); }
public static Bitmap RenderPage(IntPtr context, IntPtr document, IntPtr page, double zoomFactor) { var pageBound = new Rectangle(); var ctm = new Matrix(); var pix = IntPtr.Zero; var dev = IntPtr.Zero; if (App.Is64Bit) { NativeMethods.BoundPage_64(document, page, ref pageBound); } else { NativeMethods.BoundPage_32(document, page, ref pageBound); } var currentDpi = DpiHelper.GetCurrentDpi(); var zoomX = zoomFactor * (currentDpi.HorizontalDpi / DpiHelper.DEFAULT_DPI); var zoomY = zoomFactor * (currentDpi.VerticalDpi / DpiHelper.DEFAULT_DPI); // gets the size of the page and multiplies it with zoom factors var width = (int)(pageBound.Width * zoomX); var height = (int)(pageBound.Height * zoomY); // sets the matrix as a scaling matrix (zoomX,0,0,zoomY,0,0) ctm.A = (float)zoomX; ctm.D = (float)zoomY; // creates a pixmap the same size as the width and height of the page if (App.Is64Bit) { pix = NativeMethods.NewPixmap_64(context, NativeMethods.LookupDeviceColorSpace_64(context, "DeviceRGB"), width, height); } else { pix = NativeMethods.NewPixmap_32(context, NativeMethods.LookupDeviceColorSpace_32(context, "DeviceRGB"), width, height); } // sets white color as the background color of the pixmap if (App.Is64Bit) { NativeMethods.ClearPixmap_64(context, pix, 0xFF); } else { NativeMethods.ClearPixmap_32(context, pix, 0xFF); } // creates a drawing device if (App.Is64Bit) { dev = NativeMethods.NewDrawDevice_64(context, pix); } else { dev = NativeMethods.NewDrawDevice_32(context, pix); } // draws the page on the device created from the pixmap if (App.Is64Bit) { NativeMethods.RunPage_64(document, page, dev, ref ctm, IntPtr.Zero); } else { NativeMethods.RunPage_32(document, page, dev, ref ctm, IntPtr.Zero); } if (App.Is64Bit) { NativeMethods.FreeDevice_64(dev); // frees the resources consumed by the device } else { NativeMethods.FreeDevice_32(dev); // frees the resources consumed by the device } dev = IntPtr.Zero; // creates a colorful bitmap of the same size of the pixmap var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); var imageData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat); unsafe { // converts the pixmap data to Bitmap data byte *ptrSrc; if (App.Is64Bit) { ptrSrc = (byte *)NativeMethods.GetSamples_64(context, pix); // gets the rendered data from the pixmap } else { ptrSrc = (byte *)NativeMethods .GetSamples_32(context, pix); // gets the rendered data from the pixmap } var ptrDest = (byte *)imageData.Scan0; for (var y = 0; y < height; y++) { var pl = ptrDest; var sl = ptrSrc; for (var x = 0; x < width; x++) { //Swap these here instead of in MuPDF because most pdf images will be rgb or cmyk. //Since we are going through the pixels one by one anyway swap here to save a conversion from rgb to bgr. pl[2] = sl[0]; //b-r pl[1] = sl[1]; //g-g pl[0] = sl[2]; //r-b //sl[3] is the alpha channel, we will skip it here pl += 3; sl += 4; } ptrDest += imageData.Stride; ptrSrc += width * 4; } } bmp.UnlockBits(imageData); if (App.Is64Bit) { NativeMethods.DropPixmap_64(context, pix); } else { NativeMethods.DropPixmap_32(context, pix); } bmp.SetResolution(currentDpi.HorizontalDpi, currentDpi.VerticalDpi); return(bmp); }