/// <summary> /// Creates a new <see cref="RasterImage"/> from the specified file. /// </summary> /// <param name="fileName">The path to the file containing the image.</param> /// <param name="pageNumber">The number of the page in the file from which the image should be created, starting at 0. Only useful for multi-page formats, such as PDF.</param> /// <param name="scale">The scale factor at which to render the image.</param> /// <param name="alpha">A boolean value indicating whether transparency (alpha) data from the image should be preserved or not.</param> /// <param name="interpolate">A boolean value indicating whether the image should be interpolated when it is resized or not.</param> public RasterImageFile(string fileName, int pageNumber = 0, double scale = 1, bool alpha = true, bool interpolate = true) { using (MuPDFContext context = new MuPDFContext()) { using (MuPDFDocument document = new MuPDFDocument(context, fileName)) { RoundedRectangle roundedBounds = document.Pages[pageNumber].Bounds.Round(scale); this.Width = roundedBounds.Width; this.Height = roundedBounds.Height; this.HasAlpha = alpha; this.Interpolate = interpolate; this.Id = Guid.NewGuid().ToString(); int imageSize = document.GetRenderedSize(pageNumber, scale, alpha ? MuPDFCore.PixelFormats.RGBA : MuPDFCore.PixelFormats.RGB); this.ImageDataAddress = Marshal.AllocHGlobal(imageSize); this.DataHolder = new DisposableIntPtr(this.ImageDataAddress); GC.AddMemoryPressure(imageSize); document.Render(pageNumber, scale, alpha ? MuPDFCore.PixelFormats.RGBA : MuPDFCore.PixelFormats.RGB, this.ImageDataAddress); } } }
/// <summary> /// Creates a new <see cref="RasterImage"/> from the specified stream. /// </summary> /// <param name="imageStream">The stream containing the image data.</param> /// <param name="fileType">The type of the image contained in the stream.</param> /// <param name="pageNumber">The number of the page in the file from which the image should be created, starting at 0. Only useful for multi-page formats, such as PDF.</param> /// <param name="scale">The scale factor at which to render the image.</param> /// <param name="alpha">A boolean value indicating whether transparency (alpha) data from the image should be preserved or not.</param> /// <param name="interpolate">A boolean value indicating whether the image should be interpolated when it is resized or not.</param> public RasterImageStream(Stream imageStream, InputFileTypes fileType, int pageNumber = 0, double scale = 1, bool alpha = true, bool interpolate = true) { using (MuPDFContext context = new MuPDFContext()) { IntPtr originalImageAddress; long originalImageLength; IDisposable toBeDisposed = null; GCHandle handleToFree; if (imageStream is MemoryStream ms) { int origin = (int)ms.Seek(0, SeekOrigin.Begin); originalImageLength = ms.Length; handleToFree = GCHandle.Alloc(ms.GetBuffer(), GCHandleType.Pinned); originalImageAddress = handleToFree.AddrOfPinnedObject(); } else { MemoryStream mem = new MemoryStream((int)imageStream.Length); imageStream.CopyTo(mem); toBeDisposed = mem; int origin = (int)mem.Seek(0, SeekOrigin.Begin); originalImageLength = mem.Length; handleToFree = GCHandle.Alloc(mem.GetBuffer(), GCHandleType.Pinned); originalImageAddress = handleToFree.AddrOfPinnedObject(); } using (MuPDFDocument document = new MuPDFDocument(context, originalImageAddress, originalImageLength, fileType)) { RoundedRectangle roundedBounds = document.Pages[pageNumber].Bounds.Round(scale); this.Width = roundedBounds.Width; this.Height = roundedBounds.Height; this.HasAlpha = alpha; this.Interpolate = interpolate; this.Id = Guid.NewGuid().ToString(); int imageSize = document.GetRenderedSize(pageNumber, scale, alpha ? MuPDFCore.PixelFormats.RGBA : MuPDFCore.PixelFormats.RGB); this.ImageDataAddress = Marshal.AllocHGlobal(imageSize); this.DataHolder = new DisposableIntPtr(this.ImageDataAddress); GC.AddMemoryPressure(imageSize); document.Render(pageNumber, scale, alpha ? MuPDFCore.PixelFormats.RGBA : MuPDFCore.PixelFormats.RGB, this.ImageDataAddress); } handleToFree.Free(); toBeDisposed?.Dispose(); } }
/// <summary> /// Generates a thumbnail of the page. /// </summary> /// <returns>A <see cref="WriteableBitmap"/> containing the thumbnail of the page.</returns> private WriteableBitmap GenerateThumbnail() { //Render the whole page. Rectangle bounds = Document.Pages[this.FindControl <PDFRenderer>("MuPDFRenderer").PageNumber].Bounds; //Determine the appropriate zoom factor to render a thumbnail of the right size for the NavigatorCanvas, taking into account DPI scaling double maxDimension = Math.Max(bounds.Width, bounds.Height); double zoom = 200 / maxDimension * ((VisualRoot as ILayoutRoot)?.LayoutScaling ?? 1); //Get the actual size in pixels of the image. RoundedRectangle roundedBounds = bounds.Round(zoom); //Initialize the image WriteableBitmap bmp = new WriteableBitmap(new PixelSize(roundedBounds.Width, roundedBounds.Height), new Vector(96, 96), Avalonia.Platform.PixelFormat.Rgba8888, AlphaFormat.Unpremul); //Render the page to the bitmap, without marshaling. using (ILockedFramebuffer fb = bmp.Lock()) { Document.Render(this.FindControl <PDFRenderer>("MuPDFRenderer").PageNumber, bounds, zoom, PixelFormats.RGBA, fb.Address); } return(bmp); }