I'm writing a program in PowerShell that uses iText 7 DLLs. I use a DLL disassembly tool, IText DLLs, and iText sample/example C# code and convert the sample C# code to PowerShell code.
For example:
iText Sample code
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(writer);
PowerShell
[itext.kernel.pdf.PdfWriter]$newPdfWriter = New-Object itext.kernel.pdf.PdfWriter(($outputFolderPath + "\" + $newPdfName))
[itext.kernel.pdf.PdfDocument]$newPdfDoc = New-Object itext.kernel.pdf.PdfDocument($newPdfWriter)
There is a line of code in some example iText c# code that I don't understand. See Figure 1 below
. Although I converted the code to the right of assignment operator ok, I can't figure out the code to the left of the assignment operator. I thought I just needed to define an object of type URL
and assign the results of the call to UrlUtil.toURL
to the URL
object. But, my approach fails. (Note: UrlUtil.toURL
is a method in an iText
class and returns a Microsoft [System.Uri]
object and TEST3
is a string constant, i.e, a path name to an image file).
//Figure 1
URL url3 = UrlUtil.toURL(TEST3);
I looked up URL
in the iText API index
(http://itextsupport.com/apidocs/itext7/latest/). It tells me that URL
is a static variable
in the class com.itextpdf.kernel.pdf.PdfName
. I disassembled itext.kernel.dll
that I'm using and I see what looks like an example of variable initialization: public static readonly PdfName URL = PdfName.CreateDirectName(nameof (URL));
See Figure 2
below for context.
In PowerShell, if URL
were a class, I'd define a URL
object like this: [itext.kernel.pdf.PdfName.URL]$url = {a System.Uri object variable}
. But, URL
is a static, readonly
variable, not a class. When I run this PowerShell code, I get Unable to find type [itext.kernel.pdf.PdfName.URL]
which makes sense since URL
is not a class. Also, when I model this fragment in Visual Studio, I get an error: "Static readonly field cannot be assigned to (except in a static constructor or a variable initializer)"
(see screenshot with c# code). I've researched this error but don't understand it either.
So, the c# code URL url3 = UrlUtil.toURL(TEST3);
looks like a System.Uri
object is being assigned to an object of type URL
.
What is actually happening here at run time in the iText C# sample code?
How do I define an object of type URL
?
//Figure 2
namespace iText.Kernel.Pdf
{
public class PdfName : PdfPrimitiveObject, IComparable<PdfName>
{
.
.
public static readonly PdfName URL = PdfName.CreateDirectName(nameof (URL));
protected internal string value;
.
.
private static PdfName CreateDirectName(string name)
{
return new PdfName(name, true);
}
public PdfName(string value)
{
this.value = value;
}
private PdfName(string value, bool directOnly) : base(directOnly)
{
this.value = value;
}
public PdfName(byte[] content) : base(content)
{
}
private PdfName()
{
}
.
.
}
}
As it turns out, it may be that the line of code in question (URL url3 = UrlUtil.toURL(TEST3);
) in the iText tutorial (https://developers.itextpdf.com/content/itext-7-building-blocks/chapter-3) may be incorrect or deprecated. The call to UrlUtil.toURL(TEST3)
returns type System.Uri
and the method CreateSource
accepts a System.Uri
, so the use of the type URL
variable (url3
in the example) is not needed.
// iText Tutorial
URL url3 = UrlUtil.toURL(TEST3);
IRandomAccessSource ras3 = new RandomAccessSourceFactory().createSource(url3);
RandomAccessFileOrArray raf3 = new RandomAccessFileOrArray(ras3);
int pages3 = TiffImageData.getNumberOfPages(raf3);
for (int i = 1; i <= pages3; i++)
{
img = new Image(
ImageDataFactory.createTiff(url3, true, i, true));
document.add(img);
}
document.close();
This code works to convert a multi-page TIF to a PDF
using iText.IO.Font;
using iText.IO.Image;
using iText.IO.Source;
using iText.IO.Util;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace x_console
{
class Program
{
static void Main(string[] args)
{
PdfWriter writer = new PdfWriter("C:\\Users\\Bill\\Desktop\\out.pdf");
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
Uri tiffFqn = UrlUtil.ToURL("C:\\Users\\Bill\\Desktop\\Multipage Test Image.tif");
IRandomAccessSource iRandomAccessSource = new RandomAccessSourceFactory().CreateSource(tiffFqn);
RandomAccessFileOrArray randomAccessFileOrArray = new RandomAccessFileOrArray(iRandomAccessSource);
int tiffPageCount = TiffImageData.GetNumberOfPages(randomAccessFileOrArray);
for (int i = 1; i <= tiffPageCount; i++)
{
Image tiffPage = new Image(ImageDataFactory.CreateTiff(tiffFqn, true, i, true));
document.Add(tiffPage);
}
document.Close();
}
}
}