예제 #1
0
        /// <summary>
        /// Generates all PDF pages as JPEG files for a given pdf source and a destination folder.
        /// </summary>
        /// <param name="source">The PDF source</param>
        /// <param name="destination">The destination folder</param>
        /// <param name="width">Used to get a smaller or bigger JPEG file, depending on the specified value</param>
        /// <param name="password">The password for the pdf file (if required)</param>
        public static void GeneratePagesAtWidth(IPdfSource source, string destination, int width, string password = null)
        {
            if (!Directory.Exists(destination))
            {
                throw new DirectoryNotFoundException("The directory \"" + destination + "\" does not exist !");
            }

            using (var stream = new PdfFileStream(source))
            {
                ValidatePassword(stream.Document, password);
                int pageCount  = CountPages(source);
                var currentDpi = DpiHelper.GetCurrentDpi();

                for (int i = 0; i < pageCount; i++)
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();

                    IntPtr p   = NativeMethods.LoadPage(stream.Document, i); // loads the page
                    var    bmp = RenderPageAtWidth(stream.Context, stream.Document, p, width, currentDpi.HorizontalDpi, currentDpi.VerticalDpi);
                    NativeMethods.FreePage(stream.Document, p);              // releases the resources consumed by the page
                    bmp.Save(Path.Combine(destination, i + generateOutputExtension), generateOutputFormat);
                }
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        private void DragMoveCurrentWindow(object sender, MouseButtonEventArgs e)
        {
            if (WindowState == WindowState.Maximized)
            {
                var dpi = DpiHelper.GetCurrentDpi();

                // MouseDevice.GetPosition() returns device-dependent coordinate, however WPF is not like that
                var point = PointToScreen(e.MouseDevice.GetPosition(this));

                Left = point.X / (dpi.HorizontalDpi / DpiHelper.DEFAULT_DPI) - RestoreBounds.Width * 0.5;
                Top  = point.Y / (dpi.VerticalDpi / DpiHelper.DEFAULT_DPI);

                WindowState = WindowState.Normal;
            }

            DragMove();
        }
예제 #3
0
        /// <summary>
        /// Extracts a PDF page as a Bitmap for a given pdf source and a page number.
        /// </summary>
        /// <param name="source">The PDF source</param>
        /// <param name="pageNumber">Page number, starting at 0</param>
        /// <param name="zoomFactor">Used to get a smaller or bigger Bitmap, depending on the specified value</param>
        /// <param name="password">The password for the pdf file (if required)</param>
        public static BitmapSource ExtractPageAtScale(IPdfSource source, int pageNumber, float zoomFactor = 1.0f, string password = null)
        {
            if (pageNumber < 0 || pageNumber >= CountPages(source))
            {
                throw new ArgumentOutOfRangeException("pageNumber", "The page \"" + pageNumber + "\" does not exist !");
            }

            using (var stream = new PdfFileStream(source))
            {
                ValidatePassword(stream.Document, password);

                IntPtr p          = NativeMethods.LoadPage(stream.Document, pageNumber); // loads the page
                var    currentDpi = DpiHelper.GetCurrentDpi();
                var    bmp        = RenderPageAtScale(stream.Context, stream.Document, p, zoomFactor, currentDpi.HorizontalDpi, currentDpi.VerticalDpi);
                NativeMethods.FreePage(stream.Document, p); // releases the resources consumed by the page

                return(bmp.ToBitmapSource());
            }
        }
예제 #4
0
        static Bitmap RenderPage(IntPtr context, IntPtr document, IntPtr page, float zoomFactor)
        {
            Rectangle pageBound = NativeMethods.BoundPage(document, page);
            Matrix    ctm       = new Matrix();
            IntPtr    pix       = IntPtr.Zero;
            IntPtr    dev       = IntPtr.Zero;

            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
            int width  = (int)(pageBound.Width * zoomX);
            int height = (int)(pageBound.Height * zoomY);

            // sets the matrix as a scaling matrix (zoomX,0,0,zoomY,0,0)
            ctm.A = zoomX;
            ctm.D = zoomY;

            // creates a pixmap the same size as the width and height of the page
            pix = NativeMethods.NewPixmap(context, NativeMethods.FindDeviceColorSpace(context, "DeviceRGB"), width, height);
            // sets white color as the background color of the pixmap
            NativeMethods.ClearPixmap(context, pix, 0xFF);

            // creates a drawing device
            dev = NativeMethods.NewDrawDevice(context, pix);
            // draws the page on the device created from the pixmap
            NativeMethods.RunPage(document, page, dev, ctm, IntPtr.Zero);

            NativeMethods.FreeDevice(dev);             // frees the resources consumed by the device
            dev = IntPtr.Zero;

            // creates a colorful bitmap of the same size of the pixmap
            Bitmap 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  = (byte *)NativeMethods.GetSamples(context, pix); // gets the rendered data from the pixmap
                byte *ptrDest = (byte *)imageData.Scan0;
                for (int y = 0; y < height; y++)
                {
                    byte *pl = ptrDest;
                    byte *sl = ptrSrc;
                    for (int 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);

            NativeMethods.DropPixmap(context, pix);
            bmp.SetResolution(currentDpi.HorizontalDpi, currentDpi.VerticalDpi);

            return(bmp);
        }
예제 #5
0
        private static Bitmap RenderPage(IntPtr context, IntPtr page, float zoomFactor)
        {
            Rectangle pageBound = NativeMethods.BoundPage(context, page);
            Matrix    ctm       = new Matrix();
            IntPtr    pix       = IntPtr.Zero;
            IntPtr    dev       = IntPtr.Zero;

            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
            int width  = (int)(pageBound.Width * zoomX);
            int height = (int)(pageBound.Height * zoomY);

            // sets the matrix as a scaling matrix (zoomX,0,0,zoomY,0,0)
            ctm.A = zoomX;
            ctm.D = zoomY;

            // creates a pixmap the same size as the width and height of the page
#if UNSAFE
            pix = NativeMethods.NewPixmap(context, NativeMethods.FindDeviceColorSpace(context, ColorSpace.Rgb), width, height, IntPtr.Zero, 0);
#else
            // use BGR color space to save byte conversions
            pix = NativeMethods.NewPixmap(context, NativeMethods.FindDeviceColorSpace(context, ColorSpace.Bgr), width, height, IntPtr.Zero, 0);
#endif
            // sets white color as the background color of the pixmap
            NativeMethods.ClearPixmap(context, pix, 0xFF);

            // creates a drawing device
            var im = Matrix.Identity;
            dev = NativeMethods.NewDrawDevice(context, im, pix);
            // draws the page on the device created from the pixmap
            NativeMethods.RunPage(context, page, dev, ctm, IntPtr.Zero);

            NativeMethods.CloseDevice(context, dev);
            NativeMethods.DropDevice(context, dev); // frees the resources consumed by the device
            dev = IntPtr.Zero;

            // creates a colorful bitmap of the same size of the pixmap
            Bitmap bmp       = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            var    imageData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat);
#if UNSAFE
            // note: unsafe conversion from pixmap to bitmap
            // without the overhead of P/Invokes, the following code can run faster than the safe-conversion code below
            unsafe {                                                            // converts the pixmap data to Bitmap data
                byte *ptrSrc  = (byte *)NativeMethods.GetSamples(context, pix); // gets the rendered data from the pixmap
                byte *ptrDest = (byte *)imageData.Scan0;
                for (int y = 0; y < height; y++)
                {
                    byte *pl = ptrDest;
                    byte *sl = ptrSrc;
                    for (int 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
                        pl   += 3;
                        sl   += 3;
                    }
                    ptrDest += imageData.Stride;
                    ptrSrc  += width * 3;
                }
            }
#else
            // note: Safe-conversion from pixmap to bitmap
            var source = NativeMethods.GetSamples(context, pix);
            var target = imageData.Scan0;
            for (int y = 0; y < height; y++)
            {
                // copy memory line by line
                NativeMethods.RtlMoveMemory(target, source, width * 3);
                target = (IntPtr)(target.ToInt64() + imageData.Stride);
                source = (IntPtr)(source.ToInt64() + width * 3);
            }
#endif
            bmp.UnlockBits(imageData);

            NativeMethods.DropPixmap(context, pix);
            bmp.SetResolution(currentDpi.HorizontalDpi, currentDpi.VerticalDpi);

            return(bmp);
        }