Ghostscript rasterizer.GetPage returns null c# - c#

I´m trying to get an image from PDF with Ghostcript.NET in C#. I have installed Ghostscript dll already (both 32 and 64 bit) and added the reference in the proyect. I´ve just taken the example for the web and it gives me an error (img was null) and i don´t know why. This is the code:
`using System;
using Ghostscript.NET.Rasterizer;
using System.IO;
using Ghostscript.NET;
using System.Drawing.Imaging;
namespace StackOverflowExample
{
class Program
{
static void Main(string[] args)
{
int desired_dpi = 96;
string inputPdfPath = #"C:\Users\orubio\Documents\Pruebas\test.pdf";
string outputPath = #"C:\Users\orubio\Documents\Pruebas\";
GhostscriptVersionInfo gvi = new GhostscriptVersionInfo(#"C:\Program Files (x86)\gs\gs9.56.1\bin\gsdll32.dll");
using (var rasterizer = new GhostscriptRasterizer())
{
rasterizer.Open(inputPdfPath, gvi, false);
for (var pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
var pageFilePath = Path.Combine(outputPath, string.Format("Page-{0}.png", pageNumber));
var img = rasterizer.GetPage(desired_dpi, pageNumber);
img.Save(pageFilePath, ImageFormat.Png);
Console.WriteLine(pageFilePath);
}
}
}
}
}`
img null error
Ty everyone :D

Related

Signing existing PDF document sometimes causes a corrupt file

I am writing a demo proof of concept to add electronic signatures to existing PDFs. I am running into one weird problem that I don't get. It seems that adding the signature to some documents works fine while adding one to others does not work and a corrupt file is generated that Adobe Reader can not open.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iText;
using iText.Kernel.Pdf;
using System.IO;
using iText.Layout;
using iText.Layout.Element;
using iText.Kernel.Geom;
using Org.BouncyCastle.Crypto.Tls;
using iText.Signatures;
using System.Collections.ObjectModel;
using Org.BouncyCastle.Pkcs;
using System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Crypto;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using iText.IO.Image;
namespace LTVSkilrikjaDemo
{
class Program
{
static void Main(string[] args)
{
string welcomeText = "Welcome to LTVSkilríkjaDemotolid!";
string pressEnterToTry = "Commands: 's' - sign, 'stop' - stops the programme";
Console.WriteLine(welcomeText);
Console.WriteLine(pressEnterToTry);
// Base directory prepared
string basedir = AppDomain.CurrentDomain.BaseDirectory;
int index = basedir.IndexOf(#"bin\");
basedir = basedir.Remove(index);
string readString = Console.ReadLine().ToLower();
while(!readString.Equals("stop"))
{
if(readString.Equals("c"))
{
string inFile = "Infile2.pdf";
string outFile = "Outfile2.pdf";
// Open PDF document and decide where to write the new document
PdfWorker worker = new PdfWorker();
worker.ReadPdf(basedir + "App_Data\\InFiles\\" + inFile, basedir + "App_Data\\OutFiles\\" + outFile);
// Start working on certificate
X509Store store = new X509Store("My");
store.Open(OpenFlags.ReadOnly);
Collection<Org.BouncyCastle.X509.X509Certificate> xcertificates = new Collection<Org.BouncyCastle.X509.X509Certificate>();
foreach (X509Certificate2 mCert in store.Certificates)
{
if (mCert.Subject.IndexOf("CN=Róbert") > -1)
{
xcertificates.Add(Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(mCert));
}
}
Org.BouncyCastle.X509.X509Certificate[] certificatesProcessed = new Org.BouncyCastle.X509.X509Certificate[xcertificates.Count];
for(int i = 0; i < xcertificates.Count; i++)
{
certificatesProcessed[i] = xcertificates[i];
}
var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(store.Certificates[5].PrivateKey).Private;
try
{
worker.Sign(certificatesProcessed, pk, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CADES, "No apparent raisin!", "Lost in Iceland", null, null, null, 0, true, basedir);
}
catch(Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error! " + ex.Message + "\n\r" + ex.StackTrace);
if(ex.InnerException != null)
{
Console.WriteLine("Inner exception: " + ex.InnerException.Message);
}
Console.ForegroundColor = ConsoleColor.Gray;
}
}
else if(!readString.Equals("stop"))
{
Console.WriteLine("Command not understood. Understand only 's' and 'stop'.");
}
readString = Console.ReadLine();
}
Console.WriteLine("Goodbye!");
System.Threading.Thread.Sleep(500);
}
}
public class PdfWorker
{
private PdfDocument _document;
private string _source;
private string _dest;
public void ReadPdf(string source, string dest)
{
_source = source;
_dest = dest;
}
public void Sign(Org.BouncyCastle.X509.X509Certificate[] chain, Org.BouncyCastle.Crypto.ICipherParameters pk,
string digestAlgorithm, PdfSigner.CryptoStandard subfilter, string reason,
string location, Collection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
int estimatedSize, bool initial, string baseDir)
{
File.Copy(_source, _dest, true);
FileStream f = new FileStream(_dest, FileMode.Append);
try
{
PdfSigner signer = new PdfSigner(new PdfReader(_source), f, true);
_document = signer.GetDocument();
_document.AddNewPage();
// Work the last page
Rectangle pageSize = _document.GetLastPage().GetPageSizeWithRotation();
//PdfWriter w = _document.GetWriter();
//long currentPos = w.GetCurrentPos();
float llx = pageSize.GetWidth() - 350 - 20; //pageSize.GetWidth() / 2 - 350 / 2;
float lly = pageSize.GetHeight() - 50 - 20; // pageSize.GetHeight() / 2 - 150 / 2;
float urx = 350; //llx + 350;
float ury = 50; //lly + 150;
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
appearance.SetPageRect(new Rectangle(llx, lly, urx, ury));
appearance.SetReason(reason);
appearance.SetLocation(location);
byte[] imagebytes = File.ReadAllBytes(baseDir + "App_Data\\UndirskriftDemo.png");
// It is not possible to use the path as it contains Icelandic characters
// which itext chokes on. We use byte array instead
ImageData imgData = ImageDataFactory.Create(imagebytes);
Image img = new Image(imgData);
img = img.ScaleToFit(350.0f, 50.0f);
appearance.SetImage(imgData);
int pageCount = _document.GetNumberOfPages();
// Creating the appearance
if(initial == true)
{
signer.SetCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
}
appearance.SetPageNumber(pageCount);
Rectangle rect = new Rectangle(10, 50, 350, 50);
appearance.SetPageRect(rect).SetPageNumber(pageCount);
appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
signer.SetFieldName(signer.GetNewSigFieldName());
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
signer.SignDetached(pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
Console.WriteLine("Signing successful!");
}
catch(Exception ex)
{
throw ex;
}
finally
{
_document.Close();
f.Close();
}
}
}
}
Please see the documents here then. Infile1.pdf I can not sign but Infile2.pdf is signed fine. Outfile1.pdf is the corrupt file.
https://app.box.com/s/52jqe8qirl80km6hunxucs00dntx70o5
What causes this? Is there something about the input PDF file or the above programme?
The problem is in your program, more exactly in your PdfWorker.Sign method:
File.Copy(_source, _dest, true);
FileStream f = new FileStream(_dest, FileMode.Append);
try
{
PdfSigner signer = new PdfSigner(new PdfReader(_source), f, true);
...
Here you first copy the file to sign to the destination and then append the PdfSigner output to it.
But that PdfSigner output is the complete signed PDF, i.e. the source plus an additional revision in which the signature is added. Thus, in the destination file you eventually have two copies of the source and then some signing additions generated under the assumptions that only one copy of the source precedes.
To fix this problem, simply remove the File.Copy(_source, _dest, true) operation and don't open the FileStream with FileMode.Append.
Even after this correction, signing of the OP's sample file "Infile1.PDF" still creates a broken PDF while signing the sample file "Infile2.pdf" now succeeds. The cause is the iText 7.0.0 bug explained in this answer which (as far as I can see) is fixed in 7.0.1. As the "Infile1.PDF" uses object streams while "Infile2.pdf" does not, only the former file is affected.

Error while opening csv file in C#

I'm stuck here while opening and reading csv file in c# program. Ive just started working upon ILNumerics to display 3D matrix graph, but the Exception rises with
"Could not find file 'C:\Users\asd\Documents\Visual Studio 2013\Projects\matrixgraph\martix\bin\Debug\stats.csv'."
Please help me out!
Below is the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using ILNumerics;
using ILNumerics.Drawing;
using ILNumerics.Drawing.Plotting;
namespace martix
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ilPanel1_Load(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
string path = #"C:\Users\asd\Documents\Visual Studio 2013\Projects\matrixgraph\martix\bin\Debug\stats.csv";
StreamReader sr = new StreamReader(File.Open(path, FileMode.Open));
string dataLines = string.Empty;
while (sr.Peek() != -1)
dataLines += sr.ReadLine().Replace(";", ",") + "\n";
sr.Close();
dataLines = dataLines.Trim('\n');
//Convert the data-string into an ILArray
ILArray<int> AN = ILMath.csvread<int>(dataLines);
//Create a new scene, which is the base for our graph
var scene = new ILScene();
using (ILScope.Enter())
{
//Convert all data points to float
ILArray<float> A = ILMath.tosingle(AN);
//Add a plot to the scene and configure it
scene.Add(new ILPlotCube
{
//Render in 3D
TwoDMode = false,
//Add 3 axes
Axes =
{
XAxis =
{
Label = { Text = "Price in $" },
GridMajor =
{
DashStyle = DashStyle.Dashed,
Color = Color.DarkGray,
Width = 1
}
},
YAxis =
{
Label = { Text = "Rating count" },
GridMajor =
{
DashStyle = DashStyle.Dashed,
Color = Color.DarkGray,
Width = 1
}
},
ZAxis =
{
Label = { Text = "Download count" }
}
},
//Add the data points
Children = {
new ILPoints {
Positions = A
},
},
//Set start rotation for 3D rendered graph
Rotation = Matrix4.Rotation(new Vector3(1, 1, 1), 0.5f)
});
}
//Add the scene to the ILPanel
ilPanel1.Scene = scene;
}
}
}
It may be the spaces you have in the path. Nevermind, you're using verbatim string.
Are you sure that path is accessible and is not a networked mapped path? Can you move your file temporarily? It really seems that you don't have access to that path.
Also you should try doing the following to pinpoint the issue:
System.IO.FileInfo fi = null;
try
{
fi = new System.IO.FileInfo(path);
}
catch (ArgumentException) {... }
catch (System.IO.PathTooLongException) {... }
catch (NotSupportedException) {... }
if (ReferenceEquals(fi, null))
{
...
// file name is not valid
}
else
{
...
// file name is valid... May check for existence by calling fi.Exists.
}
EDIT:
use System.IO.Directory.GetFiles to list the exact names of the files in that folder, it may be that the file name is different (stats.csv.csv) and window explorer is hiding the extension.
Got the solution while trying. I created the csv file programatically and this time it read the file.
Just added the few line before the path and modified the path.
StringBuilder csv = new StringBuilder();
csv.AppendLine("112,113,222");
string csvpath = #"C:\\stats\xyz.csv";
File.AppendAllText(csvpath,csv.ToString());
string path = #"C:\stats\xyz.csv";
And thats it. Anyways Thanks for helping :)

ObjectARX read/write .dwg files that are not currently opened in autocad

Im trying to modify a .dwg file and overwrite the .dwg file once done, all that without opening it in autocad. I've read about RealDWG but the goal here is not to be in a standalone mode. the autocad plugin runs from autocad and needs to modify and write to some .dwg files that are not opened in the current project. So far I create a Database object and Read the .dwg file into it but im having errors when I want to rewrite into it. Here is the code its in C#,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ModifyClosedDWG
{
public class DWGEditor
{
private static string filepath = #"E:\...\DrawingTest.dwg";
[CommandMethod("modifyDWG")]
public void addTextToDWG()
{
Database workingDB = HostApplicationServices.WorkingDatabase;
Editor ed = doc.Editor;
Database db = new Database(false, true);
try
{
db.ReadDwgFile(filepath, System.IO.FileShare.ReadWrite, false, "");
db.CloseInput(true);
HostApplicationServices.WorkingDatabase = db;
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
ed.WriteMessage("\nUnable to read drawing file : " + e.StackTrace);
return;
}
using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
{
using (BlockTableRecord btr = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite) as BlockTableRecord)
{
MText objText = new MText();
objText.SetDatabaseDefaults();
objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2, 2, 0);
objText.Contents = "added text in a closed .dwg file!";
objText.TextStyleId = db.Textstyle;
btr.AppendEntity(objText);
}
}
HostApplicationServices.WorkingDatabase = workingDB;
db.SaveAs(filepath, DwgVersion.Current);
}
}
}
the error output :
Autodesk.AutoCAD.Runtime.Exception: eWasOpenForWrite
at Autodesk.AutoCAD.DatabaseServices.Database.SaveAs(String fileName, DwgVersion version)
at ModifyClosedDWG.DWGEditor.addTextToDWG() in E:\PROJETS\ELI017\07 In Works documents\VisualC#Projects\ModifyClosedDWG\ModifyClosedDWG\DWGEditor.cs:line 64
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
I found the solution so I'll put the new code here...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ModifyClosedDWG
{
public class DWGEditor
{
private static string filepath = #"E:\PROJETS\ELI017\07 In Works documents\dwg\DrawingTest.dwg";
[CommandMethod("modifyDWG")]
public void addTextToDWG()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database workingDB = HostApplicationServices.WorkingDatabase;
Database db = new Database(false, true);
try
{
db.ReadDwgFile(filepath, System.IO.FileShare.ReadWrite, false, "");
db.CloseInput(true);
HostApplicationServices.WorkingDatabase = db;
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
ed.WriteMessage("\nUnable to open .dwg file : " + e.StackTrace);
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
MText objText = new MText();
objText.SetDatabaseDefaults();
objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2, 2, 0);
objText.Contents = "added text in a closed .dwg file!";
objText.TextStyleId = db.Textstyle;
btr.AppendEntity(objText);
tr.AddNewlyCreatedDBObject(objText, true);
tr.Commit();
}
HostApplicationServices.WorkingDatabase = workingDB;
db.SaveAs(filepath, DwgVersion.Current);
}
}
}

Change value of PropertyTagImageDescription

I'm trying to solve the problem of changing the value PropertyTagImageDescription (0x010E) for the Bitmap object. To add a description for the file. Searching the related topics, and has not found the solution. My use:
Bitmap image = new Bitmap(Image.FromFile(fileName));
var data = System.Text.Encoding.UTF8.GetBytes("My comment");
PropertyItem propItem = image.GetPropertyItem(Convert.ToInt32(0x010E));
propItem.Len = data.Length;
propItem.Value = data;
image.SetPropertyItem(propItem);
But there is an error : "In GDI + error occurred generic."
Help me understand! What I'm doing wrong?
I can't get to your error I haven't found a image that has the 0x010E property set. But I have build a little console application that works:
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
class Program
{
static void Main(string[] args)
{
string imageLocation = #"C:\Users\Jens\Desktop\image.jpg";
string newImageLocation = #"C:\Users\Jens\Desktop\newImage.jpg";
// http://msdn.microsoft.com/en-us/library/ms534415(VS.85).aspx
Int32 ImageDescription = 0x010E;
// get file stream and create Image
using (var fs = new FileStream(imageLocation, FileMode.Open, FileAccess.ReadWrite))
using (var img = Image.FromStream(fs, false, false))
{
var data = Encoding.UTF8.GetBytes("My comment");
// get a property from the image file and use it as container
var propItem = img.PropertyItems.FirstOrDefault();
// set the values that u like to add
// http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem.aspx
propItem.Type = 2;
propItem.Id = ImageDescription;
propItem.Len = data.Length;
propItem.Value = data;
// add property to Image and save it to the system
img.SetPropertyItem(propItem);
img.Save(newImageLocation);
}
}
}

Unable to open CSV file from internet using C#

I'm new with C#. I've written code to open a CSV file from my documents on my local machine. It works well and the data parsing works. Trouble is when I change the code to open the file from an internet site I cannot get it to work. I am able to open this file using VBA but I now want to use C# ADO.NET. I cannot find the answer by searching with Google. Can anyone help with the code and/or point me to a website with a good tutorial. All help much appreciated. Code attached, I'm sure the problem is with lines 24 - 26;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//
// Read in a file line-by-line, and store it all in a List.
//
int i = 0;
DateTime dte;
List<string> list = new List<string>();
float[] Prices = new float[4];
WebClient wc = new WebClient();
byte[] data = wc.DownloadData("http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
using (StreamReader reader = new StreamReader(wc))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//list.Add(line); // Add to list.
Console.WriteLine(line); // Write to console.
string[] parts = line.Split(',');
int DateSetter = 1;
int DateDone = 0;
int CountFloat = 0;
int PricesDone = 0;
Double Volume = 0;
foreach (string part in parts)
{
Console.WriteLine("{0} : {1}", i, part);
if (DateSetter == 1)
{
dte = DateTime.Parse(part);
DateSetter = 2;
Console.WriteLine(dte);
}
if (DateDone == 1)
{
if (DateSetter < 6)
{
Prices[CountFloat] = float.Parse(part);
CountFloat++;
DateSetter++;
Console.WriteLine(Prices[3]);
}
}
DateDone = 1;
if (PricesDone == 1)
{
Volume = double.Parse(part);
Console.WriteLine(Volume);
}
if (DateSetter == 6)
{
PricesDone = 1;
}
}
}
}
Console.ReadLine();
}
}
}
Your code as pasted would not compile. You can however use the WebClient to download to a string, then split the string into lines:
string content;
using(WebClient wc = new WebClient())
content = wc.DownloadString("http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
foreach(var line in content.Split(new string [] {Environment.NewLine}, StringSplitOptions.None))
{
//...
}
Another option is to download data as you're doing, and then wrap it with a MemoryStream:
WebClient wc = new WebClient();
byte[] data = wc.DownloadData(
"http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
using (var ms = new MemoryStream(data))
{
using (var reader = new StreamReader(ms))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// do whatever
}
}
}
The advantage of this over splitting the string is that it uses considerably less memory.

Categories