iTextSharp - How to convert PdfPTable to JPEG or other image format?
I believe iTextSharp does not currently support rendering PDF into image files. Ghostscript supports converting PDF files to images. There is a good tutorial here available to convert PDF files to images. Also you can use rendering object like this one.
iTextSharp is only for creating PDF Documents.
There are many other DLL's that can be used to convert PDF to JPG. The most preferred is Ghostscript(GS). you can use the foll. C# Code with GS dll
public static void PdfToJpg(string input, string output)
{
PdfToImage.PDFConvert pp = new PDFConvert();
pp.OutputFormat = "jpeg"; //format
pp.JPEGQuality = 100; //100% quality
pp.ResolutionX = 300; //dpi
pp.ResolutionY = 300;
pp.FirstPageToConvert = 1; //pages you want
pp.LastPageToConvert = 1;
pp.Convert(input , output );
}
namespace PdfToJpeg
{
{
PDFConvert converter = new PDFConvert();
public Form1()
{
InitializeComponent();
}
try
{
PdfToJpg("c:\abc.pdf","c:\" + "output.jpg");
MessageBox.Show("Files Converted");
}
catch (Exception ex)
{
MessageBox.Show("Exception Error Occured... " + ex.Message.ToString());
}
}
}
Related
I have a pdf document where I am filling all the values using the below code.
using(MemoryStream ms = new MemoryStream())
{
// Fill the PDF with the XFA
using(PdfStamper stamper = new PdfStamper(oInPDF, ms))
{
stamper.Writer.CloseStream = false;
XfaForm.SetXfa(oXFA, stamper.Reader, stamper.Writer);
}
// Code for Flatten the filled PDF.
}
I am trying to draw a box in red around the value displayed to highlight when the values are not in the expected range.
I would like to know, how do I locate the position of a control on a pdf page using iTextSharp and C#.
Any help or info on this, much appreciated.
Many Thanks.
Finally managed to draw borders around controls with below code.
XmlDocument newXMLDoc = new XmlDocument();
newXMLDoc.LoadXml(#"<border><edge thickness=""1.3mm""><color value=""0, 0, 255""/></edge></border>");
if (Rs.Rows.Count > 0)
{
foreach (DataRow query in Rs.Rows)
{
if(isRET)
{
if (oXFA.DomDocument.SelectSingleNode("//t:*[#name='" + Rs[0] + "']", oNameSpace) != null)
{
XmlNode newNode =
oXFA.DomDocument.ImportNode(newXMLDoc.SelectSingleNode("border"), true);
oXFA.DomDocument.SelectSingleNode("//t:*[#name='" + Rs[0] + "']", oNameSpace).AppendChild(newNode);
}
}
}
}
Windows 8.1 Pro, Visual Studio 2015 Update 3, C#, .NET Framework 4.5. Ghostscript.NET (latest), GhostScript 9.20.
I'm converting a PDF to a PDF. Hah. Well, I'm making an "editable" PDF "hard" PDF that can't be edited and is of lower quality. The process is I take the editable PDF, save it out as x-pages of PNG files, convert those PNG files to a multipage TIFF, and then convert the multipage TIFF to the PDF I need.
This worked just fine with Visual Studio 2012, one version earlier of GhostScript .NET and GS 9.10.
public static Tuple<string, List<string>> CreatePNGFromPDF(string inputFile, string outputfile)
{
Tuple<string, List<string>> t = null;
List<string> fileList = new List<string>();
string message = "Success";
string outputFileName = string.Empty;
int desired_x_dpi = 96;
int desired_y_dpi = 96;
try
{
using (GhostscriptViewer gsViewer = new GhostscriptViewer())
{
gsViewer.Open(inputFile);
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer(gsViewer))
{
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
using (System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber))
{
outputFileName = outputfile.Replace(".png", string.Empty) + "_page_" + pageNumber.ToString() + ".png";
img.Save(outputFileName, ImageFormat.Png);
if (!fileList.Contains(outputFileName))
{
fileList.Add(outputFileName);
}
}
}
}
}
}
catch (Exception ex)
{
message = ex.Message;
}
t = new Tuple<string, List<string>>(message, fileList);
return t;
}
This now fails on this line:
using (System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber))
when processing the second page. The first page works okay.
I downloaded the source for GhostScript.NET, added it to my solution, debugged, etc., and spent a good long while trying to figure this out.
I then decided to separate out the functionality and make the bare minimum available for me to examine further in a simple Console application:
static void Main(string[] args)
{
int xDpi = 96;
int yDpi = 96;
string pdfFile = #"Inputfilenamehere.pdf";
GhostscriptVersionInfo gsVersionInfo = GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL | GhostscriptLicense.AFPL, GhostscriptLicense.GPL);
List<GhostscriptVersionInfo> gsVersionInfoList = GhostscriptVersionInfo.GetInstalledVersions(GhostscriptLicense.GPL | GhostscriptLicense.AFPL);
try
{
using (GhostscriptViewer gsViewer = new GhostscriptViewer())
{
gsViewer.Open(pdfFile);
using (GhostscriptRasterizer gsRasterizer = new GhostscriptRasterizer(gsViewer))
{
int pageCount = gsRasterizer.PageCount;
for (int i = 0; i < pageCount; i++)
{
Image img = gsRasterizer.GetPage(xDpi, yDpi, i + 1);
}
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Lo and behold, no problems. The difference is that I'm not putting declaration of my Image in the using statement.
I always try to be a good boy developer and use a using statement whenever the class implements IDisposable.
So, I removed the use of the using and I get the lower-quality PDF's that I've always desired. My life is good now.
using (GhostscriptViewer gsViewer = new GhostscriptViewer())
{
gsViewer.Open(inputFile);
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer(gsViewer))
{
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber);
outputFileName = outputfile.Replace(".png", string.Empty) + "_page_" + pageNumber.ToString() + ".png";
img.Save(outputFileName, ImageFormat.Png);
if (!fileList.Contains(outputFileName))
{
fileList.Add(outputFileName);
}
}
}
}
Note that if I call img.Dispose() at the end of the for loop, I get the same error again!
My best guess is that my issue is not a GhostScript or GhostScript.NET issue. Am I being a bonehead for insisting on blindly using "using" statements if the class implements IDisposable? I've always understood that it's best practice to wrap anything that implements IDisposable with a using statement to forgo leaks, etc.
Hence, my question: Any ideas why I get the "Parameter is invalid" exception when I initialize the System.Drawing.Image class within the using statement but not when I don't? I'd love to understand this more.
Better yet, if anyone knows how I can get this functionality and also ensure I'm properly disposing my object, that would be the best.
I didn't find much about this particular topic when I searched for information. I did find one other StackOverflow post about someone using a graphic object in a using statement with the same error. I wonder if there is a relationship. I also note that I should be using Dispose(), but that appears to be causing the problem, and I need this to work.
FYI, for anyone interested, the actual error occurs here in GhostscriptInterprester.cs in the GhostScript.NET code:
Method: public void Run(string str)
str is "Page pdfshowpage_init pdfshowpage_finish"
// GSAPI: run the string
int rc_run = _gs.gsapi_run_string(_gs_instance, str, 0, out exit_code);
I found the root cause of my failure at least. My GhostscriptRasterizer object had a value of '0' set for the height points and width points.
var rasterizer = new GhostscriptRasterizer();
rasterizer.CustomSwitches.Add("-dDEVICEWIDTHPOINTS=" + widthPoints);
rasterizer.CustomSwitches.Add("-dDEVICEHEIGHTPOINTS=" + heightPoints);
Once I set both height and width to a valid non-zero value, the issue got fixed.
thanks for take the time to read my odd issue with PDFSharp.
I use PDFSharp Library Version 1.50.4000.0 (I update from 1.3.2 and have the same issue) at the time to protect a PDF file with a password.
The program works very good with portrait documents but some times I have documents with mixed orientations.
But all the times when a landscape page it's in the document the page is cutted.
The code for your reference:
PdfDocument document = PdfReader.Open(System.IO.Path.Combine("H:/Bloq1/", file.Name), "PasswordHere");
PdfSecuritySettings securitySettings = document.SecuritySettings;
securitySettings.OwnerPassword = "PasswordHere";
securitySettings.PermitAccessibilityExtractContent = false;
securitySettings.PermitAnnotations = false;
securitySettings.PermitAssembleDocument = false;
securitySettings.PermitExtractContent = false;
securitySettings.PermitFormsFill = true;
securitySettings.PermitFullQualityPrint = true;
securitySettings.PermitModifyDocument = false;
securitySettings.PermitPrint = true;
document.Save(System.IO.Path.Combine("H:/Bloq1/", file.Name));
tbx.Text = "Complete";
tbx.Background = Brushes.ForestGreen;
Thanks in advance for your time reading or answering this question =D
*****************************Solved*********************************************
I switch to iTextSharp and test a couple of documents and works pretty well I'll share the code for reference:
private void Button_Full(object sender, RoutedEventArgs e)//PROTEGE PDF PERMITIENDO IMPRESION
{
string Password = "password";
DirectoryInfo dir = new DirectoryInfo("H:/Bloq1/");
if(dir.GetFiles("*.pdf").Length ==0)
{
MessageBox.Show("There are no files in the default directory", "No Files", MessageBoxButton.OK, MessageBoxImage.Warning);
tbx.Background = Brushes.OrangeRed;
tbx.Text = "No Files Found";
}
else
{
tbx.Background = Brushes.White;
tbx.Text = "Protecting....";
foreach (FileInfo file in dir.GetFiles("*.pdf"))
{
try
{
string InputFile = System.IO.Path.Combine("H:/Bloq1/", file.Name);
string OutputFile = System.IO.Path.Combine("H:/Bloq1/", "#"+file.Name);
using (Stream input = new FileStream(InputFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (Stream output = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(input);
PdfEncryptor.Encrypt(reader, output, true, null, Password, PdfWriter.AllowPrinting);
}
}
file.Delete();
File.Move(#"H:\Bloq1\#"+file.Name, #"H:\Bloq1\"+file.Name);
tbx.Text = "Full Protected";
tbx.Background = Brushes.ForestGreen;
}
catch (Exception ex)
{
tbx.Text = "Error in: " + file.Name + ex;
tbx.Background = Brushes.IndianRed;
}
}
}
}
For those that believe "I switched to iText" is not an answer, I've found a "fix" for PDFSharp.
Without diving into the source code PDFSharp appears to do a redundant rotation on landscape pages. This corrected the landscape pages in documents I worked with that had both portrait and landscape pages.
PdfPages pageCollection = pdfDoc.Pages;
for (int i = 0; i < pageCollection.Count; i++)
{
if (pageCollection[i].Orientation.ToString().Equals("Landscape"))
{
if (pageCollection[i].Rotate == 90)
{
pageCollection[i].Orientation = PageOrientation.Portrait;
}
}
}
If you use the source code version of PDFsharp you can make this change in PdfPage.cs to see if it solves your problem:
internal PdfPage(PdfDictionary dict)
: base(dict)
{
// Set Orientation depending on /Rotate.
//int rotate = Elements.GetInteger(InheritablePageKeys.Rotate);
//if (Math.Abs((rotate / 90)) % 2 == 1)
// _orientation = PageOrientation.Landscape;
}
I'd be glad to see feedback if you have to make further changes to get it working.
See also:
http://forum.pdfsharp.net/viewtopic.php?p=9591#p9591
I switch to iTextSharp and test a couple of documents and works pretty well I'll share the code for reference in the top.
Thank You to all
Since PDFSharp can only properly handle transformations on portrait pages, my work-around was converting the landscape pages to portrait with .page.Rotate = 0 and then applying my transformations while accounting for that the page was now sideways. Before saving the file, I converted the page back to landscape with .page.Rotate = 90. Worked fine!
I had this same problem with my pages getting cut off. That's why its important to rotate the pages instead of directly changing the Page.Orientation attribute!
I'm trying to insert images in my rich text box in C#, but so far I'm only failing. Miserably.
This is the code that I am using:
Clipboard.SetImage(Image.FromFile(Application.StartupPath + #"\PIC\" + i + ".bmp"));
chat.Paste();
The real problem is I am not able to put both text and image in the textbox. The moment I insert text after copying the image the image disappears. I am unable to find a solution for this
Can anybody help me with this? Please???
Thanks
RichTextBox rtb = new RichTextBox();
byte[] headerImage = (byte[])(dr["ImageData"]);
string imageData = string.Empty;
if (headerImage != null && headerImage.Length > 0)
{
Bitmap bmp = new Bitmap(new MemoryStream(headerImage));
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0;
imageData = #"{\pict\jpegblip\picw10449\pich3280\picwgoal9924\pichgoal1860\ " + BitConverter.ToString(ms.ToArray()).Replace("-", string.Empty).ToLower() + "}";
ms.Dispose();
}
string finalrtfdata = rtb.Rtf;
finalrtfdata = finalrtfdata.Replace("&ImageHeader&", imageData);
// finalrtfdata contain your image data along with rtf tags.
Try this out,you can paste this into your code and call it:
place a picture into your project to embeded resource,and call this method
passing the richtextbox.
private void createImage(Control item)
{
Hashtable image = new Hashtable(1);
image.Add(item,yourproject.Properties.Resources.yourpicturename);
Clipboard.SetImage((Image)image[item]);
((RichTextBox)item).Paste();
}
private static void createImage(RichTextBox item)
{
var image = new Hashtable(1) { { item, Properties.Resources.yourimage } };
Clipboard.SetImage((Image)image[item]);
item.Paste();
}
I have an excel workbook vsto solution that needs to generate a pdf copy of one of its sheets as output.
I have a license for abcdpdf .net and tried outputting to html, then using abcpdf to convert the html to pdf, but the excel html markup tries to emulate excel with all 4 worksheets with horrible markup. It also messes up the colors (silver background across entire workbook).
Any suggestions?
Here is the code I'm currently using to generate the html file:
FileInfo excelDoc = new FileInfo(Globals.ThisWorkbook.Path + #"\Document.html");
Globals.Sheet2.SaveAs(excelDoc.FullName,
Excel.XlFileFormat.xlHtml, missing, missing, false, false,
Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing);
If I hack away some of the html header tags manually, I can get abcdpf to accept it, but the formatting is a bit off and this solution seems sub optimal.
Thanks in advance.
Solution found: store excel sheet as XPS print out. Import XPS printout into pdf document.
MyImportOperation code adapted from abcpdf XPS sample source code.
public void SaveSheetToPdf(FileInfo outputPDF)
{
FileInfo documentFile = new FileInfo(Globals.ThisWorkbook.Path + #"\tempDoc.xps");
if (documentFile.Exists)
documentFile.Delete();
Globals.Sheet2.PrintOut(1, missing, 1, false, "Microsoft XPS Document Writer", true, false, documentFile.FullName);
Doc theDoc = new Doc();
try
{
MyImportOperation importOp = new MyImportOperation(theDoc);
importOp.Import(documentFile);
}
catch (Exception ex)
{
throw new Exception("Error rendering pdf. PDF Source XPS Path: " + investmentPlanXPSPath, ex);
}
theDoc.Save(outputPDF.FullName);
}
public class MyImportOperation
{
private Doc _doc = null;
private double _margin = 10;
private int _pagesAdded = 0;
public MyImportOperation(Doc doc)
{
_doc = doc;
}
public void Import(string inPath)
{
using (XpsImportOperation op = new XpsImportOperation())
{
op.ProcessingObject += Processing;
op.ProcessedObject += Processed;
op.Import(_doc, inPath);
}
}
public void Processing(object sender, ProcessingObjectEventArgs e)
{
if (e.Info.SourceType == ProcessingSourceType.PageContent)
{
_doc.Page = _doc.AddPage();
e.Info.Handled = true;
_pagesAdded++;
}
}
public void Processed(object sender, ProcessedObjectEventArgs e)
{
if (e.Successful)
{
PixMap pixmap = e.Object as PixMap;
if (pixmap != null)
pixmap.Compress();
}
}
}