I have finally, successfully, figured out how to fill a PDF with an XFA Form with my custom data using iTextSharp.
The problem is that I've lost the code that I had that let me make the XFA read-only. I have made the horrible mistake of changing my code before committing a working version to my source control. And now, after searching Google for like an hour I still can't find it :( If someone could remind me of the code that would be much appreciated.
PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(pdfFileName);
PdfStamper stamper = new PdfStamper(reader, ms);
XfaForm xfa = new XfaForm(reader);
XmlDocument doc = new XmlDocument();
doc.LoadXml(CreateXmaData(XDocument.Parse(xfa.DomDocument.InnerXml)));
xfa.DomDocument = doc;
xfa.Changed = true;
XfaForm.SetXfa(xfa, stamper.Reader, stamper.Writer);
PdfAction action = new PdfAction(PdfAction.PRINTDIALOG);
stamper.Writer.SetOpenAction(action);
// Somewhere here I had the code that made my XFA form read only...
stamper.Writer.CloseStream = false;
stamper.Close();
reader.Close();
byte[] buffer = new byte[ms.Position];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
return buffer;
Not sure if I was dreaming that I had the read-only working or what, and I doubt that this is the best way, but here is how I was finally able to do it:
...
doc.LoadXml(CreateXmaData(XDocument.Parse(xfa.DomDocument.InnerXml)));
PdfAction readOnlyAction = PdfAction
.JavaScript(MakeReadOnly(xfa.DomDocument.InnerXml), stamper.Writer);
stamper.Writer.AddJavaScript(readOnlyAction);
xfa.DomDocument = doc;
...
private string MakeReadOnly(string xml)
{
string formName = string.Empty;
int subFormStart = xml.IndexOf("<subform", 0);
if (subFormStart > -1)
{
int nameTagStart = xml.IndexOf("name", subFormStart);
int nameStart = xml.IndexOf("\"", nameTagStart);
int nameEnd = xml.IndexOf("\"", nameStart + 1);
formName = xml.Substring(nameStart + 1, (nameEnd - nameStart) - 1);
}
string readOnlyFunction = "ProcessAllFields(xfa.form." + formName + ");";
readOnlyFunction += "function ProcessAllFields(oNode) {";
readOnlyFunction += " if (oNode.className == \"exclGroup\" || oNode.className == \"subform\" || oNode.className == \"subformSet\" || oNode.className == \"area\") { ";
readOnlyFunction += " for (var i = 0; i < oNode.nodes.length; i++) {";
readOnlyFunction += " var oChildNode = oNode.nodes.item(i); ProcessAllFields(oChildNode);";
readOnlyFunction += " }";
readOnlyFunction += " } else if (oNode.className == \"field\") {";
readOnlyFunction += " oNode.access = \"readOnly\"";
readOnlyFunction += " }";
readOnlyFunction += "}";
return readOnlyFunction;
}
This worked for me
String script = "for (var nPageCount = 0; nPageCount < xfa.host.numPages; nPageCount++) { var oFields = xfa.layout.pageContent(nPageCount, \"subform\"); var nNodesLength = oFields.length;";
script += "for (var nNodeCount = 0; nNodeCount < nNodesLength; nNodeCount++) { oFields.item(nNodeCount).access = \"readOnly\"; } } ";
Related
I am working on a WinForms application. I use the pdf file to reset the password and the values on pdf are stored as key-value pairs(email: xxxx#mail.com, pass: 11111).
What I want to do:
Read the PDF file line by line and fill the appropriate textboxes.
What I Have done:
public bool CreatePDF(string location, string email, string key)
{
if(location != "" && email != "" && key != "")
{
PdfWriter pdfwriter = new PdfWriter(location);
PdfDocument pdf = new PdfDocument(pdfwriter);
Document document = new Document(pdf);
Paragraph fields = new Paragraph("Email: "+email + "\n" + "Secret Key: "+key);
document.Add(fields);
document.Close();
return true;
}
else
{
return false;
}
}
public string ReadPDF(string location)
{
var pdfDocument = new PdfDocument(new PdfReader(location));
StringBuilder processed = new StringBuilder();
var strategy = new LocationTextExtractionStrategy();
string text = "";
for (int i = 1; i <= pdfDocument.GetNumberOfPages(); ++i)
{
var page = pdfDocument.GetPage(i);
text += PdfTextExtractor.GetTextFromPage(page, strategy);
processed.Append(text);
}
return text;
}
}
Thank you in advance Guys!. Any suggestions on CreatePDF are also welcome.
This is what I came up with,
var pdfDocument = new PdfDocument(new PdfReader("G:\\Encryption_File.pdf"));
StringBuilder processed = new StringBuilder();
var strategy = new LocationTextExtractionStrategy();
string text = "";
for (int i = 1; i <= pdfDocument.GetNumberOfPages(); ++i)
{
var page = pdfDocument.GetPage(i);
text += PdfTextExtractor.GetTextFromPage(page, strategy);
processed.Append(text);
}
text.Split('\n');
string line = "";
line = text + "&";
string[] newLines = line.Split('&');
textBox1.Text = newLines[0].Split(':')[1].ToString();
textBox2.Text = newLines[0].Split(':')[2].ToString();
I am using Dynamsoft Barcode Readeing Dll In My Barcode Reader Project.I am getting Correct Output Of Given Barcode at Running Time But With Output I am getting License error.How can I solve it...Just I am only using Barcode dll..
Here With I have Attached That Output screenshot And code...
[License Error Screen Shot
{
Stopwatch watch = new Stopwatch();
BarcodeReader reader = new BarcodeReader();
public String BarcodePathAndName = "";
int i = 0, n = 0;
public bool nextimgs = true;
ThreadClassnextImage obj = new ThreadClassnextImage();
public Barcodes()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
obj.BcH += obj_BcH;
}
private void obj_BcH(Image BarcodeNextImages, string barcodeImagePath)
{
rTbBarCodeResults.Text = "";
PbLoadBarcodeImage.Image = BarcodeNextImages;
watch.Reset();
watch.Start();
BarcodeResult[] result = reader.DecodeFile(barcodeImagePath);
n = result.Length;
for (i = 0; i < n; i++)
{
BarcodeResult barcode = result[i];
rTbBarCodeResults.Text = rTbBarCodeResults.Text + barcode.BarcodeFormat.ToString() + "\r\n";
rTbBarCodeResults.Text = rTbBarCodeResults.Text + barcode.BarcodeText + "\r\n";
rTbBarCodeResults.Text = rTbBarCodeResults.Text + barcode.BarcodeData.ToString() + "\r\n";
watch.Stop();
rTbBarCodeResults.Text += "\n\nTotal Sec: " + watch.Elapsed.TotalSeconds+"\r\n";
rTbBarCodeResults.Text+="\r\nTotal Minutes: "+watch.Elapsed.TotalMinutes+"\r\n";
rTbBarCodeResults.Text+="\r\nTotal Mill Seconds: "+watch.Elapsed.TotalMilliseconds+"\r\n";
rTbBarCodeResults.Text+="\r\nTotal Nano Seconds:"+watch.Elapsed.TotalMilliseconds*1000000+"\r\n";
}
}`
`]1
Dynamsoft Barcode Reader is a commercial software. You have to set a valid license, trial or full, as follows:
BarcodeReader reader = new BarcodeReader { LicenseKeys = "t0260NQAAAFUZbbNi3xJ4oViu+0+5Eim8wPzn6GeJZrIvrb/HLjzJ8Mn+GRjbfdoa/f+iRLzKTudXVEkKqj9tKlzzDP+xKzZ2IdknzMXimKDmKBivdKTXM3T5ACPK25omqoQkqNw00zExtCrR532mHig0QU6dsF5EmvkgDLxsbWw/M54wj1F1pGagM7YfKzpLN0/qvCeejimX2nvTMfOzv+M37m+0RPsnyp20pITycnvBGyWkZ3OWQ97U8UNYl+OyyfuHymz8EcjqQm9nxvYTm4nYHERHkiXMmI6jWLgK+4+jIlcS9WLgWd8pMKkI0bZCcwmVzk5z+vuGYKjZVK/iuYIx7McOP9k=" };
You can get the trial license from the SDK installer.
I have a problem with printing a pdf.
So my Document is being created by writing some values in a pdf document and saving it
public void CreateDocument(string name)
{
string oldreport = #"..\Resources\FehlerReport.pdf";
string newreportpath = #"..\Resources\" + name;
using (var newFileStream = new FileStream(newreportpath, FileMode.Create))
{
var pdfReader = new PdfReader(oldreport);
var stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
form.SetField("Auftragsnummer", Kundeninformation.Auftragsnummer.ToString());
form.SetField("Kundensachnummer", Kundeninformation.Kundensachnummer.ToString());
form.SetField("Kundenname", Kundeninformation.Kundenname.ToString());
form.SetField("Kundenbestellnummer", Kundeninformation.Kundenbestellnummer.ToString());
form.SetField("Kundenrezepturnummer", Kundeninformation.Kundenrezepturnummer.ToString());
form.SetField("Spulennummer", Kundeninformation.Spulennummer.ToString());
form.SetField("Fertigungsdatum1", System.DateTime.Today.ToString("dd.MM.yy"));
int i = 1;
foreach (var item in _MeasurementReport.MeasurementReportItems)
{
form.SetField(("UhrzeitRow" + i).ToString(), item.Uhrzeit.ToString("HH:mm:ss"));
form.SetField(("FehlerindexRow" + i).ToString(), i.ToString());
form.SetField(("Position mmRow" + i).ToString(), (item.Laufmeter * pixelSize).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));
form.SetField(("HoeheRow" + i).ToString(), (item.DefectCountours.H * pixelSize).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));
form.SetField(("Breite mmRow" + i).ToString(), (item.DefectCountours.W * pixelSize).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));
form.SetField(("Flaeche Row" + i).ToString(), (item.DefectCountours.W * pixelSize * pixelSize).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));
i++;
}
form.SetField("Datum", System.DateTime.Today.ToString("dd.MM.yy"));
form.SetField("Uhrzeit", System.DateTime.Now.ToString("HH:mm"));
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
}
}
So now i want to print the document with this function, which also calls the CreateDocument function. It prints, but the paper is white. I checked if the created pdf is being created, and it is being created but apparently not printed.
public void Print()
{
string name = Kundeninformation.Auftragsnummer + "_" + Kundeninformation.Spulennummer+".pdf";
CreateDocument(name);
List<string> PrinterFound = new List<string>();
PrinterSettings printer = new PrinterSettings();
foreach (var item in PrinterSettings.InstalledPrinters)
{
PrinterFound.Add(item.ToString());
}
printer.PrinterName = PrinterFound[7];
printer.PrintFileName = name;
PrintDocument PrintDoc = new PrintDocument();
PrintDoc.DocumentName = #"..\Resources\"+name;
PrintDoc.PrinterSettings.PrinterName = PrinterFound[7];
PrintDoc.Print();
}
make sure your file is created completely.. otherwise you will this issue. to test quickly put some delay between file creation and printing
I am using threads to upload images on a FTP. Now I have a problem in limiting the number of threads. when I am creating same number of threads equal to images then it's fine i.e. it is working fine. But now I want to create only suppose maximum of 5 number of threads to upload 100 or more images. I have a datatable in which these 100 images are with a unique field ID which stores suppose 0,1,2,3....and so on for every images. Now I want to start only five threads once so that it may start uploading 5 images parallely. On a Timer, I am checking the status of threads and if I found a thread which is not live now, I want to assign it the 6th Image for uploading and in the same way, if I found other thread which finished its uploading/work, I want to give it 7th image to upload and so on. i.e. this process will run until 100 images are uploaded.
Can you please suggest me a structure by using which I may achieve this? Currently I am creating 100 threads for 100 images and it is working perfect. But I am afraid of creating that much number of threads. Will that affect performance?
My Current Code is:
// A page level variable
Thread [] tr=null;
//On Load of the Control
tr = new Thread[dt.Rows.Count];
//tr = new Thread[MaxID];
for (int i = 0; i < dt.Rows.Count; i++)
//for (int i = 0; i < MaxID; i++)
{
tr[i] = new Thread(new ThreadStart(ProcessItems));
tr[i].Name = Convert.ToString(dt.Rows[i]["Id"]);
tr[i].IsBackground = true;
}
//Start each thread
foreach (Thread x in tr)
{
x.Start();
}
//The method which is used to upload images
public object tLock = new object();
private void ProcessItems()
{
//if (dict.Count == 0)
// pthread.Suspend();
//ArrayList toRemove = new ArrayList();
lock (tLock)
{
try
{
//int NoofAttempts = 0;
//foreach (DictionaryEntry e in dict)
//{
//Thread.Sleep(500);
dr = dt.Select("Is_Uploaded=0 And Id=" + Thread.CurrentThread.Name).FirstOrDefault();
uxImageAndProgress pbCtl = panelControl1.Controls[dr["Image_ID"].ToString()] as uxImageAndProgress;
//NoofAttempts = 0;
string Path = "";
if (ftpPath == "")
{
Path = Global.FTPRemotePath + "/ProductImages/" + dr["Image_ID"] + dr["Extension"].ToString();
}
else
{
Path = ftpPath + dr["Image_ID"] + dr["Extension"].ToString();
}
//object[] loader = e.Value as object[];
int length = (int)(dr["ActualData"] as byte[]).Length;
Stream stream = new MemoryStream(dr["ActualData"] as byte[]);
byte[] rBuffer = ReadToEnd(stream);
int d = length - (int)stream.Length;
d = Math.Min(d, rnd.Next(10) + 1);
if (ftpRequest == null)
{
try
{
#region New Code
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(Path));
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(Global.FTPLogIn, Global.FTPPassword);
ftpRequest.UsePassive = true;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.Timeout = 20000;
ftpRequest.ContentLength = length;
byte[] buffer = new byte[length > 4097 ? 4097 : length];
int bytes = 0;
int total_bytes = (int)length;
System.IO.Stream rs = ftpRequest.GetRequestStream();
while (total_bytes > 0)
{
bytes = stream.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
dr["Is_Uploaded"] = 1;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
rs.Close();
#endregion
}
catch (Exception eeex)
{
ftpRequest = null;
if (ErrorText == "")
ErrorText = eeex.Message.ToString();
else
ErrorText = ErrorText + "," + eeex.Message.ToString();
if (Image_IDsToDelete == "")
Image_IDsToDelete = dr["Image_ID"].ToString();
else
Image_IDsToDelete = Image_IDsToDelete + "," + dr["Image_ID"].ToString();
if (NotUploadedFiles == "")
NotUploadedFiles = Convert.ToString(dr["FileName"]);//dr["Image_ID"] + dr["Extension"].ToString();
else
NotUploadedFiles = NotUploadedFiles + ", " + Convert.ToString(dr["FileName"]);
dr["Is_Uploaded"] = true;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
pbCtl.Is_WithError = true;
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message.ToString(), Global.Header, MessageBoxButtons.OK);
//pthread.Suspend();
}
}
}
//The Timer Event on which I am checking the Status of threads and taking appropriate action
private void timer1_Tick(object sender, EventArgs e)
{
bool Is_AllFinished=true;
//Start each thread
foreach (Thread x in tr)
{
if (x.IsAlive == true)
{
Is_AllFinished = false;
break;
}
else
{
//DataRow[] drs = dt.Select("Is_Uploaded=0");
//if (drs.Count() > 0)
//{
//x. = Convert.ToString(MaxID + 1);
//x.Start();
//MaxID = MaxID + 1;
//}
}
}
if (Is_AllFinished == true)
{
timer1.Enabled = false;
if (Image_IDsToDelete != "")
{
RetailHelper.ExecuteNonQuery("Delete from images where Image_ID in (" + Image_IDsToDelete + ")");
}
if (ErrorText != "")
{
NotUploadedFiles = NotUploadedFiles + ".";
XtraMessageBox.Show("Unable to connect to server. The following files were not uploaded:" + System.Environment.NewLine + NotUploadedFiles + ".", Global.Header, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Is_Done = true;
}
}
Now, I want to convert this code to use a fixed number of threads. Please help me.
Thanking you!
Use a Semaphore it is good enough. You can polish the code yourself.
const int maxThreads = 5;
Semaphore sm = new Semaphore(maxThreads, maxThreads); // maximum concurrent threads
for (int i = 0; i < dt.Rows.Count; i++)
{
try
{
sm.WaitOne();
Thread tr = new Thread(new ThreadStart(ProcessItems));
tr.Name = Convert.ToString(dt.Rows[i]["Id"]);
tr.IsBackground = true;
tr.Start();
}
finally
{
sm.Release();
}
}
// You don't need the timer anymore
// Wait for the semaphore to be completely released
for (int i=0; i<maxThreads ; i++)
sm.WaitOne();
sm.Release(maxThreads);
if (Image_IDsToDelete != "")
{
RetailHelper.ExecuteNonQuery("Delete from images where Image_ID in (" + Image_IDsToDelete + ")");
}
if (ErrorText != "")
{
NotUploadedFiles = NotUploadedFiles + ".";
XtraMessageBox.Show("Unable to connect to server. The following files were not uploaded:" + System.Environment.NewLine + NotUploadedFiles + ".", Global.Header, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
//The method which is used to upload images
private void ProcessItems()
{
//if (dict.Count == 0)
// pthread.Suspend();
//ArrayList toRemove = new ArrayList();
try
{
sm.WaitOne();
try
{
//int NoofAttempts = 0;
//foreach (DictionaryEntry e in dict)
//{
//Thread.Sleep(500);
dr = dt.Select("Is_Uploaded=0 And Id=" + Thread.CurrentThread.Name).FirstOrDefault();
uxImageAndProgress pbCtl = panelControl1.Controls[dr["Image_ID"].ToString()] as uxImageAndProgress;
//NoofAttempts = 0;
string Path = "";
if (ftpPath == "")
{
Path = Global.FTPRemotePath + "/ProductImages/" + dr["Image_ID"] + dr["Extension"].ToString();
}
else
{
Path = ftpPath + dr["Image_ID"] + dr["Extension"].ToString();
}
//object[] loader = e.Value as object[];
int length = (int)(dr["ActualData"] as byte[]).Length;
Stream stream = new MemoryStream(dr["ActualData"] as byte[]);
byte[] rBuffer = ReadToEnd(stream);
int d = length - (int)stream.Length;
d = Math.Min(d, rnd.Next(10) + 1);
if (ftpRequest == null)
{
try
{
#region New Code
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(Path));
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(Global.FTPLogIn, Global.FTPPassword);
ftpRequest.UsePassive = true;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.Timeout = 20000;
ftpRequest.ContentLength = length;
byte[] buffer = new byte[length > 4097 ? 4097 : length];
int bytes = 0;
int total_bytes = (int)length;
System.IO.Stream rs = ftpRequest.GetRequestStream();
while (total_bytes > 0)
{
bytes = stream.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
dr["Is_Uploaded"] = 1;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
rs.Close();
#endregion
}
catch (Exception eeex)
{
ftpRequest = null;
if (ErrorText == "")
ErrorText = eeex.Message.ToString();
else
ErrorText = ErrorText + "," + eeex.Message.ToString();
if (Image_IDsToDelete == "")
Image_IDsToDelete = dr["Image_ID"].ToString();
else
Image_IDsToDelete = Image_IDsToDelete + "," + dr["Image_ID"].ToString();
if (NotUploadedFiles == "")
NotUploadedFiles = Convert.ToString(dr["FileName"]);//dr["Image_ID"] + dr["Extension"].ToString();
else
NotUploadedFiles = NotUploadedFiles + ", " + Convert.ToString(dr["FileName"]);
dr["Is_Uploaded"] = true;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
pbCtl.Is_WithError = true;
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message.ToString(), Global.Header, MessageBoxButtons.OK);
//pthread.Suspend();
}
}
finally
{
sm.Release();
}
}
It sounds like a producer / consumer queue is the structure you are looking for. Take a look a this answer and the others in the thread for examples of how to employ it.
I'm developing a C# application to certify pdf documents. I've got the certification process done but now I need to take the signature image stored in a smartcard and place it in the given PDF file.
The code used to get the certificates is this:
public static X509Certificate2 GetCertificate()
{
X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = st.Certificates;
X509Certificate2 card = null;
X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(col, "Certificates", "Select one to sign", X509SelectionFlag.SingleSelection);
if (sel.Count > 0)
{
X509Certificate2Enumerator en = sel.GetEnumerator();
en.MoveNext();
card = en.Current;
}
st.Close();
return card;
}
And then I apply the chosen one to the Document here:
if(card == null)
{
ChooseCertified:
card = GetCertificate();
if (card == null)
{
DialogResult result = MessageBox.Show("Unable to identify certificates" +
Environment.NewLine + "Would you like to try again?", "Certification error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question);
if (result.CompareTo(DialogResult.Retry) == 0)
goto ChooseCertified;
else
return 1;
}
}
X509CertificateParser cp = new X509CertificateParser(card.RawData);
org.bouncycastle.x509.X509Certificate[] chain = new org.bouncycastle.x509.X509Certificate[] { cp.ReadCertificate() };
PdfReader reader = new PdfReader(original_pdf_file);
PdfStamper stp = PdfStamper.CreateSignature(reader, new FileStream(result_pdf_file, FileMode.Create), '\0', null, true);
PdfSignatureAppearance sap = stp.SignatureAppearance;
sap.Layer2Text = "Document signed by " + Environment.NewLine +
card.GetNameInfo(X509NameType.SimpleName, false) + Environment.NewLine +
"Date: " + date.ToString("dd-MM-yyyy") + Environment.NewLine +
"Reason: " + REASON;
iTextSharp.text.Rectangle rct = reader.GetPageSizeWithRotation(1);
float lowerx = 0, upperx = 0, lowery = 0, uppery = 0;
if (valign == "top")
{
lowery = (rct.Height - height) - vert_margin;
uppery = rct.Height - vert_margin;
}
else
{
lowery = vert_margin;
uppery = vert_margin + height;
}
if (halign == "left")
{
lowerx = hor_margin;
upperx = hor_margin + width;
}
else
{
lowerx = (rct.Width - width) - hor_margin;
upperx = rct.Width - hor_margin;
}
sap.SetVisibleSignature(new iTextSharp.text.Rectangle(lowerx, lowery, upperx, uppery),1, null);
sap.SignDate = date;
sap.SetCrypto(null, chain, null, null);
sap.Reason = REASON;
sap.Location = LOCATION;
iTextSharp.text.Font f = new iTextSharp.text.Font(iTextSharp.text.Font.HELVETICA, 7, 1, iTextSharp.text.Color.BLACK);
f.SetStyle("Bold");
sap.Layer2Font = f;
sap.Acro6Layers = true;
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1);
dic.Date = new PdfDate(date);
dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN");
dic.Reason = REASON;
dic.Location = LOCATION;
sap.CryptoDictionary = dic;
int csize = 4000;
Hashtable exc = new Hashtable();
exc[PdfName.CONTENTS] = csize * 2 + 2;
sap.PreClose(exc);
HashAlgorithm sha = new SHA1CryptoServiceProvider();
Stream s = sap.RangeStream;
int read = 0;
byte[] buff = new byte[8192];
while ((read = s.Read(buff, 0, 8192)) > 0)
{
sha.TransformBlock(buff, 0, read, buff, 0);
}
sha.TransformFinalBlock(buff, 0, 0);
byte[] pk = SignMsg(sha.Hash, card, false);
byte[] outc = new byte[csize];
PdfDictionary dic2 = new PdfDictionary();
Array.Copy(pk, 0, outc, 0, pk.Length);
dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true));
sap.Close(dic2);
So what i need now is a way to get the signature image that is store on the card and after a lot of google searching i found nothing regarding this matter. I would really aprecciate if someone could help me with this.
Thanks in advance :)