/// <summary> /// Exports a JPEG image. /// </summary> static void ExportJpegImage(PdfDictionary image, bool flateDecode, ref int count) { // Fortunately JPEG has native support in PDF and exporting an image is just writing the stream to a file. var stream = flateDecode ? Filtering.Decode(image.Stream.Value, "/FlateDecode") : image.Stream.Value; var fs = new FileStream(String.Format("Image{0}.jpeg", count++), FileMode.Create, FileAccess.Write); var bw = new BinaryWriter(fs); bw.Write(stream); bw.Close(); }
private async Task GetImagesFromPage(PdfPage page, ImportParams importParams, ScannedImageSource.Concrete source) { if (page.CustomValues.Elements.ContainsKey("/NAPS2ImportedPage")) { source.Put(await ExportRawPdfPage(page, importParams)); return; } // Get resources dictionary var resources = page.Elements.GetDictionary("/Resources"); // Get external objects dictionary var xObjects = resources?.Elements.GetDictionary("/XObject"); if (xObjects == null) { return; } // Iterate references to external objects foreach (var item in xObjects.Elements.Values) { // Is external object an image? if (!((item as PdfReference)?.Value is PdfDictionary xObject) || xObject.Elements.GetString("/Subtype") != "/Image") { continue; } // Support multiple filter schemes var element = xObject.Elements.Single(x => x.Key == "/Filter"); var elementAsArray = element.Value as PdfArray; var elementAsName = element.Value as PdfName; if (elementAsArray != null) { var arrayElements = elementAsArray.Elements.Select(x => x.ToString()).ToArray(); if (arrayElements.Length == 2) { source.Put(DecodeImage(arrayElements[1], page, xObject, Filtering.Decode(xObject.Stream.Value, arrayElements[0]), importParams)); } } else if (elementAsName != null) { source.Put(DecodeImage(elementAsName.Value, page, xObject, xObject.Stream.Value, importParams)); } else { throw new NotImplementedException("Unsupported filter"); } } }
/// <summary> /// Unfilters the stream. /// </summary> void Decode() { if (Stream != null && Stream.Value != null) { PdfItem item = Elements["/Filter"]; if (item != null) { byte[] bytes = Filtering.Decode(Stream.Value, item); if (bytes != null) { Stream.Value = bytes; Elements.Remove("/Filter"); Elements.SetInteger("/Length", Stream.Length); } } } }
/// <summary> /// Unfilters the stream. /// </summary> void Decode() { if (Stream != null && Stream.Value != null) { PdfItem item = Elements[PdfStream.Keys.Filter]; if (item != null) { var decodeParms = Elements[PdfStream.Keys.DecodeParms]; byte[] bytes = Filtering.Decode(Stream.Value, item, decodeParms); if (bytes != null) { Stream.Value = bytes; Elements.Remove(PdfStream.Keys.Filter); Elements.Remove(PdfStream.Keys.DecodeParms); Elements.SetInteger(PdfStream.Keys.Length, Stream.Length); } } } }
private IEnumerable <ScannedImage> GetImagesFromPage(PdfPage page) { if (page.CustomValues.Elements.ContainsKey("/NAPS2ImportedPage")) { yield return(ExportRawPdfPage(page)); yield break; } // Get resources dictionary PdfDictionary resources = page.Elements.GetDictionary("/Resources"); // Get external objects dictionary PdfDictionary xObjects = resources?.Elements.GetDictionary("/XObject"); if (xObjects == null) { yield break; } // Iterate references to external objects foreach (PdfItem item in xObjects.Elements.Values) { var reference = item as PdfReference; var xObject = reference?.Value as PdfDictionary; // Is external object an image? if (xObject != null && xObject.Elements.GetString("/Subtype") == "/Image") { // Support multiple filter schemes // For JPEG: "/DCTDecode" OR ["/DCTDecode", "/FlateDecode"] // For PNG: "/FlateDecode" var element = xObject.Elements.Single(x => x.Key == "/Filter"); var elementAsArray = element.Value as PdfArray; var elementAsName = element.Value as PdfName; if (elementAsArray != null) { // JPEG ["/DCTDecode", "/FlateDecode"] yield return(ExportJpegImage(page, Filtering.Decode(xObject.Stream.Value, "/FlateDecode"))); } else if (elementAsName != null) { switch (elementAsName.Value) { case "/DCTDecode": yield return(ExportJpegImage(page, xObject.Stream.Value)); break; case "/FlateDecode": yield return(ExportAsPngImage(page, xObject)); break; case "/CCITTFaxDecode": yield return(ExportG4(page, xObject)); break; default: throw new NotImplementedException("Unsupported image encoding"); } } else { throw new NotImplementedException("Unsupported filter"); } } } }
private IEnumerable <ScannedImage> GetImagesFromPage(PdfPage page, ImportParams importParams) { if (page.CustomValues.Elements.ContainsKey("/NAPS2ImportedPage")) { yield return(ExportRawPdfPage(page, importParams)); yield break; } // Get resources dictionary PdfDictionary resources = page.Elements.GetDictionary("/Resources"); // Get external objects dictionary PdfDictionary xObjects = resources?.Elements.GetDictionary("/XObject"); if (xObjects == null) { yield break; } // Iterate references to external objects foreach (PdfItem item in xObjects.Elements.Values) { var reference = item as PdfReference; var xObject = reference?.Value as PdfDictionary; // Is external object an image? if (xObject != null && xObject.Elements.GetString("/Subtype") == "/Image") { // Support multiple filter schemes var element = xObject.Elements.Single(x => x.Key == "/Filter"); var elementAsArray = element.Value as PdfArray; var elementAsName = element.Value as PdfName; if (elementAsArray != null) { string[] arrayElements = elementAsArray.Elements.Select(x => x.ToString()).ToArray(); if (arrayElements.Length == 2) { yield return(DecodeImage(arrayElements[1], page, xObject, Filtering.Decode(xObject.Stream.Value, arrayElements[0]), importParams)); } } else if (elementAsName != null) { yield return(DecodeImage(elementAsName.Value, page, xObject, xObject.Stream.Value, importParams)); } else { throw new NotImplementedException("Unsupported filter"); } } } }