简体   繁体   中英

How to define an object apparently implemented as a static read-only field? (Using iText 7 to convert multi-page TIFF to PDF)

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, ie, 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.

我的小C#模型显示的屏幕截图

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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM