public static IEnumerable <Bitmap> GetBitmapPagesEnum(string path, float zoom = 1.0f) { IntPtr ctx = NativeMethods.NewContext(); // Creates the context IntPtr stm = NativeMethods.OpenFile(ctx, path); // opens file test.pdf as a stream IntPtr doc = NativeMethods.OpenDocumentStream(ctx, stm); // opens the document int pn = NativeMethods.CountPages(doc); // gets the number of pages in the document for (int i = 0; i < pn; i++) // iterate through each pages { IntPtr p = NativeMethods.LoadPage(doc, i); // loads the page (first page number is 0) RectangleMu b = new RectangleMu(); NativeMethods.BoundPage(doc, p, ref b); // gets the page size var page = RenderPage(ctx, doc, p, b, zoom, zoom); NativeMethods.FreePage(doc, p); // releases the resources consumed by the page yield return(page); } NativeMethods.CloseDocument(doc); // releases the resources NativeMethods.CloseStream(stm); NativeMethods.FreeContext(ctx); }
/// <summary> /// Get the page with the specified page number (1 indexed). /// </summary> /// <param name="pageNumber">The number of the page to return, this starts from 1.</param> /// <returns></returns> public Bitmap GetPage(int pageNumber, float zoom = 1.0f) { if (pageNumber <= 0 || pageNumber > PagesCount) { throw new ArgumentOutOfRangeException("pageNumber"); } if (zoom <= 0) { throw new ArgumentException("PdfImageConverter(): zoom must be positive and bigger than 0."); } IntPtr p = NativeMethods.LoadPage(_doc, pageNumber - 1); // loads the page (first page number is 0) RectangleMu b = new RectangleMu(); NativeMethods.BoundPage(_doc, p, ref b); // gets the page size var page = RenderPage(_ctx, _doc, p, b, zoom, zoom); NativeMethods.FreePage(_doc, p); // releases the resources consumed by the page return(page); }
internal RectangleMu Transform(RectangleMu rect) { Point s, t, u, v; if (rect.IsInfinite) { return(rect); } s.X = rect.Left; s.Y = rect.Top; t.X = rect.Left; t.Y = rect.Bottom; u.X = rect.Right; u.Y = rect.Bottom; v.X = rect.Right; v.Y = rect.Top; s = this.Transform(s); t = this.Transform(t); u = this.Transform(u); v = this.Transform(v); rect.Left = Min4(s.X, t.X, u.X, v.X); rect.Top = Min4(s.Y, t.Y, u.Y, v.Y); rect.Right = Max4(s.X, t.X, u.X, v.X); rect.Bottom = Max4(s.Y, t.Y, u.Y, v.Y); return(rect); }
public static int GetBitmapHeight(RectangleMu pageBound, float zoomY = 1.0f) { return((int)(zoomY * (pageBound.Bottom - pageBound.Top))); }
public static extern void BoundPage(IntPtr doc, IntPtr page, ref RectangleMu bound);
private static Bitmap RenderPage(IntPtr context, IntPtr document, IntPtr page, RectangleMu pageBound, float zoomX = 1.0f, float zoomY = 1.0f) { MatrixMu ctm = new MatrixMu(); IntPtr pix = IntPtr.Zero; IntPtr dev = IntPtr.Zero; // gets the size of the scaled page int width = GetBitmapWidth(pageBound, zoomX); // (int)(zoomX * (pageBound.Right - pageBound.Left)); int height = GetBitmapHeight(pageBound, zoomY); // (int)(zoomY * (pageBound.Bottom - pageBound.Top)); ctm.A = zoomX; ctm.D = zoomY; // sets the matrix as (zoomX,0,0,zoomY,0,0) // creates a pixmap the same size as the width and height of the page pix = NativeMethods.NewPixmap(context, NativeMethods.LookupDeviceColorSpace(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, ref 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); //bmp.SetResolution(300, 300); var imageData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat); unsafe { // converts the pixmap data to Bitmap data // gets the rendered data from the pixmap byte *ptrSrc = (byte *)NativeMethods.GetSamples(context, pix); 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; } } // free bitmap in memory bmp.UnlockBits(imageData); NativeMethods.DropPixmap(context, pix); return(bmp); }
public static int GetBitmapWidth(RectangleMu pageBound, float zoomX = 1.0f) { return((int)(zoomX * (pageBound.Right - pageBound.Left))); }