private void ApplyResizeSettings(ResizeSettings settings, GhostscriptSettings ghostscriptSettings) { // Parse resize settings // - graphicsAlphaBits int graphicsAlphaBits = settings.GetValueOrDefault("graphicsbits", 0); if (!_validAlphaBitValues.Contains(graphicsAlphaBits)) { // Use default value graphicsAlphaBits = _validAlphaBitValues.Last(); } ghostscriptSettings.Add(GhostscriptArgument.GraphicsAlphaBits, graphicsAlphaBits); // - textAlphaBits int textAlphaBits = settings.GetValueOrDefault("textbits", 0); if (!_validAlphaBitValues.Contains(textAlphaBits)) { // Use default value textAlphaBits = _validAlphaBitValues.Last(); } ghostscriptSettings.Add(GhostscriptArgument.TextAlphaBits, textAlphaBits); ghostscriptSettings[GhostscriptArgument.GridFitTT] = (settings.Get <bool>("gridfit") == true ? 2 : 0).ToString(NumberFormatInfo.InvariantInfo); ghostscriptSettings[GhostscriptArgument.AlignToPixels] = (settings.Get <bool>("subpixels") == true ? 1 : 0).ToString(NumberFormatInfo.InvariantInfo); if (settings.Get <bool>("printed", true) == false) { ghostscriptSettings.Remove(GhostscriptArgument.Printed); } }
public override Bitmap DecodeStream(Stream s, ResizeSettings settings, string optionalPath) { if (string.IsNullOrEmpty(optionalPath)) { if (s.CanSeek) { //Check the header instead if no filename is present. byte[] header = new byte[4]; s.Read(header, 0, 4); bool isPdf = (header[0] == '%' && header[1] == 'P' && header[2] == 'D' && header[3] == 'F'); s.Seek(-4, SeekOrigin.Current); //Restore position. if (!isPdf) { return(null); } } else { return(null); //It's not seekable, we can't check the header. } } else if (!SupportedExtensions.Contains(Path.GetExtension(optionalPath), StringComparer.OrdinalIgnoreCase)) { // Not a supported format return(null); } // Do not allow decoding if Ghostscript there are issues with performing this decode IIssue[] issues = GetIssues().ToArray(); if (issues.Length > 0) { string message = string.Join(Environment.NewLine, issues.Select(x => x.Summary).ToArray()); throw new InvalidOperationException(message); } using (var pdf = PdfDocument.Load(s)) { // Extract the requested page number from resize settings, or default to first page int pageNumber = settings.GetValueOrDefault("page", 1); // Try to get the page number from PDF info. If not available, abort. This is caused by // requesting a page that does not exist. if (pageNumber < 1 || pageNumber > pdf.PageCount) { return(null); } // Calculate the output size based on the actual size of the page. var pageSize = pdf.PageSizes[pageNumber - 1]; var outputSize = GetOutputSize(settings, pageSize.Width, pageSize.Height); // Build the render flags from the provided settings. var flags = BuildFlags(settings); // Generate the PDF page. return((Bitmap)pdf.Render(pageNumber - 1, outputSize.Width, outputSize.Height, 96, 96, flags)); } }
private void ApplyResizeSettings(ResizeSettings settings, GhostscriptSettings ghostscriptSettings) { // Parse resize settings // - graphicsAlphaBits int graphicsAlphaBits = settings.GetValueOrDefault("graphicsbits", 0); if(!_validAlphaBitValues.Contains(graphicsAlphaBits)) { // Use default value graphicsAlphaBits = _validAlphaBitValues.Last(); } ghostscriptSettings.Add(GhostscriptArgument.GraphicsAlphaBits, graphicsAlphaBits); // - textAlphaBits int textAlphaBits = settings.GetValueOrDefault("textbits", 0); if(!_validAlphaBitValues.Contains(textAlphaBits)) { // Use default value textAlphaBits = _validAlphaBitValues.Last(); } ghostscriptSettings.Add(GhostscriptArgument.TextAlphaBits, textAlphaBits); ghostscriptSettings[GhostscriptArgument.GridFitTT] = (settings.Get<bool>("gridfit") == true ? 2 : 0).ToString(NumberFormatInfo.InvariantInfo); ghostscriptSettings[GhostscriptArgument.AlignToPixels] = (settings.Get<bool>("subpixels") == true ? 1 : 0).ToString(NumberFormatInfo.InvariantInfo); if (settings.Get<bool>("printed",true) == false) ghostscriptSettings.Remove(GhostscriptArgument.Printed); }
public override Bitmap DecodeStream(Stream s, ResizeSettings settings, string optionalPath) { if(string.IsNullOrEmpty(optionalPath)) { if (s.CanSeek) { //Check the header instead if no filename is present. byte[] header = new byte[4]; s.Read(header, 0, 4); bool isPdf = (header[0] == '%' && header[1] == 'P' && header[2] == 'D' && header[3] == 'F'); s.Seek(-4, SeekOrigin.Current); //Restore position. if (!isPdf) return null; } else { return null; //It's not seekable, we can't check the header. } } else if(!_supportedExtensions.Contains(Path.GetExtension(optionalPath), StringComparer.OrdinalIgnoreCase)) { // Not a supported format return null; } // Do not allow decoding if Ghostscript there are issues with performing this decode IIssue[] issues = GetIssues().ToArray(); if(issues.Length > 0) { string message = string.Join(Environment.NewLine, issues.Select(x => x.Summary).ToArray()); throw new InvalidOperationException(message); } // Must write input stream to a temporary file for Ghostscript to process. FileInfo tempInputPathInfo = new FileInfo(Path.GetTempFileName()); try { using(FileStream tempInputStream = tempInputPathInfo.Create()) { StreamExtensions.CopyToStream(s, tempInputStream); } // Get information about the PDF such as page count and media boxes // Although this creates a second trip to Ghostscript engine, it's not possible to generate a rendered image in exact // dimensions requested. Skipping this step will cause a rendered image, of some size, to be resized further. PdfInfo pdfInfo = GetPdfInfo(tempInputPathInfo.FullName); // Extract the requested page number from resize settings, or default to first page int pageNumber = settings.GetValueOrDefault("page", 1); // Try to get the page number from PDF info. If not available, abort. This is caused by // requesting a page that does not exist. PageInfo pageInfo = pdfInfo.Pages.SingleOrDefault(x => x.Number == pageNumber); if(pageInfo == null) { return null; } // We only support media box (as opposed to clip, bleed, art, etc.) If this is not available, abort. if(pageInfo.MediaBox == null) { return null; } // Get the output size of the generated bitmap by applying the resize settings and media box. Size outputSize = (pageInfo.Rotate == -90 || pageInfo.Rotate == 90) ? GetOutputSize(settings, pageInfo.MediaBox.Height,pageInfo.MediaBox.Width) : GetOutputSize(settings, pageInfo.MediaBox.Width, pageInfo.MediaBox.Height) ; // Create default Ghostscript settings and apply the resize settings. GhostscriptSettings ghostscriptSettings = new GhostscriptSettings { GhostscriptArgument.NoPause, GhostscriptArgument.Quiet, GhostscriptArgument.Safer, GhostscriptArgument.Batch, {GhostscriptArgument.OutputDevice, "pngalpha"}, {GhostscriptArgument.MaxBitmap, 24000000}, {GhostscriptArgument.RenderingThreads, 4}, {GhostscriptArgument.GridFitTT, 0}, {GhostscriptArgument.AlignToPixels, 0}, //Subpixel rendering depends on output device... perhaps testing would help determine if 1 would be better? {GhostscriptArgument.FirstPage, pageNumber}, {GhostscriptArgument.LastPage, pageNumber}, GhostscriptArgument.Printed, GhostscriptArgument.PdfFitPage, GhostscriptArgument.FixedMedia, {GhostscriptArgument.Height, outputSize.Height}, {GhostscriptArgument.Width, outputSize.Width} }; ApplyResizeSettings(settings, ghostscriptSettings); // Have Ghostscript process the input to a PNG file with transparency. // The PNG will be reloaded and further processed by the resizer pipeline. FileInfo tempOutputPathInfo = new FileInfo(Path.GetTempFileName()); try { // Add output file and input file. The input file must be the very last argument. ghostscriptSettings.Add(GhostscriptArgument.OutputFile, tempOutputPathInfo.FullName); ghostscriptSettings.Add(tempInputPathInfo.FullName); _engine.Execute(ghostscriptSettings); // NOTE: Do not dispose of memory stream because it is used as the backing source for the loaded bitmap. MemoryStream memoryStream = new MemoryStream((int)tempOutputPathInfo.Length); using(FileStream fileStream = tempOutputPathInfo.Open(FileMode.Open)) { StreamExtensions.CopyToStream(fileStream, memoryStream); } // Per ImagerResizer plugin example source code: // NOTE: If the Bitmap class is used for decoding, read gdi-bugs.txt and make sure you set b.Tag to new BitmapTag(optionalPath,stream); BitmapTag bitmapTag = new BitmapTag("ghostscript.png", memoryStream); return new Bitmap(memoryStream) { Tag = bitmapTag }; } //catch(GhostscriptException) //{ // // Conversion failed // return null; //or maybe we should show details? If it's a valid PDF? //} finally { tempOutputPathInfo.Delete(); } } finally { tempInputPathInfo.Delete(); } }
public override Bitmap DecodeStream(Stream s, ResizeSettings settings, string optionalPath) { if (string.IsNullOrEmpty(optionalPath)) { if (s.CanSeek) { //Check the header instead if no filename is present. byte[] header = new byte[4]; s.Read(header, 0, 4); bool isPdf = (header[0] == '%' && header[1] == 'P' && header[2] == 'D' && header[3] == 'F'); s.Seek(-4, SeekOrigin.Current); //Restore position. if (!isPdf) { return(null); } } else { return(null); //It's not seekable, we can't check the header. } } else if (!_supportedExtensions.Contains(Path.GetExtension(optionalPath), StringComparer.OrdinalIgnoreCase)) { // Not a supported format return(null); } // Do not allow decoding if Ghostscript there are issues with performing this decode IIssue[] issues = GetIssues().ToArray(); if (issues.Length > 0) { string message = string.Join(Environment.NewLine, issues.Select(x => x.Summary).ToArray()); throw new InvalidOperationException(message); } // Must write input stream to a temporary file for Ghostscript to process. FileInfo tempInputPathInfo = new FileInfo(Path.GetTempFileName()); try { using (FileStream tempInputStream = tempInputPathInfo.Create()) { StreamExtensions.CopyToStream(s, tempInputStream); } // Get information about the PDF such as page count and media boxes // Although this creates a second trip to Ghostscript engine, it's not possible to generate a rendered image in exact // dimensions requested. Skipping this step will cause a rendered image, of some size, to be resized further. PdfInfo pdfInfo = GetPdfInfo(tempInputPathInfo.FullName); // Extract the requested page number from resize settings, or default to first page int pageNumber = settings.GetValueOrDefault("page", 1); // Try to get the page number from PDF info. If not available, abort. This is caused by // requesting a page that does not exist. PageInfo pageInfo = pdfInfo.Pages.SingleOrDefault(x => x.Number == pageNumber); if (pageInfo == null) { return(null); } // We only support media box (as opposed to clip, bleed, art, etc.) If this is not available, abort. if (pageInfo.MediaBox == null) { return(null); } // Get the output size of the generated bitmap by applying the resize settings and media box. Size outputSize = (pageInfo.Rotate == -90 || pageInfo.Rotate == 90) ? GetOutputSize(settings, pageInfo.MediaBox.Height, pageInfo.MediaBox.Width) : GetOutputSize(settings, pageInfo.MediaBox.Width, pageInfo.MediaBox.Height); // Create default Ghostscript settings and apply the resize settings. GhostscriptSettings ghostscriptSettings = new GhostscriptSettings { GhostscriptArgument.NoPause, GhostscriptArgument.Quiet, GhostscriptArgument.Safer, GhostscriptArgument.Batch, { GhostscriptArgument.OutputDevice, "pngalpha" }, { GhostscriptArgument.MaxBitmap, 24000000 }, { GhostscriptArgument.RenderingThreads, 4 }, { GhostscriptArgument.GridFitTT, 0 }, { GhostscriptArgument.AlignToPixels, 0 }, //Subpixel rendering depends on output device... perhaps testing would help determine if 1 would be better? { GhostscriptArgument.FirstPage, pageNumber }, { GhostscriptArgument.LastPage, pageNumber }, GhostscriptArgument.Printed, GhostscriptArgument.PdfFitPage, GhostscriptArgument.FixedMedia, { GhostscriptArgument.Height, outputSize.Height }, { GhostscriptArgument.Width, outputSize.Width } }; ApplyResizeSettings(settings, ghostscriptSettings); // Have Ghostscript process the input to a PNG file with transparency. // The PNG will be reloaded and further processed by the resizer pipeline. FileInfo tempOutputPathInfo = new FileInfo(Path.GetTempFileName()); try { // Add output file and input file. The input file must be the very last argument. ghostscriptSettings.Add(GhostscriptArgument.OutputFile, tempOutputPathInfo.FullName); ghostscriptSettings.Add(tempInputPathInfo.FullName); _engine.Execute(ghostscriptSettings); // NOTE: Do not dispose of memory stream because it is used as the backing source for the loaded bitmap. MemoryStream memoryStream = new MemoryStream((int)tempOutputPathInfo.Length); using (FileStream fileStream = tempOutputPathInfo.Open(FileMode.Open)) { StreamExtensions.CopyToStream(fileStream, memoryStream); } // Per ImagerResizer plugin example source code: // NOTE: If the Bitmap class is used for decoding, read gdi-bugs.txt and make sure you set b.Tag to new BitmapTag(optionalPath,stream); BitmapTag bitmapTag = new BitmapTag("ghostscript.png", memoryStream); return(new Bitmap(memoryStream) { Tag = bitmapTag }); } //catch(GhostscriptException) //{ // // Conversion failed // return null; //or maybe we should show details? If it's a valid PDF? //} finally { tempOutputPathInfo.Delete(); } } finally { tempInputPathInfo.Delete(); } }