<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: IDRSolutions</title>
    <description>The latest articles on DEV Community by IDRSolutions (@idrsolutions).</description>
    <link>https://dev.to/idrsolutions</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3078638%2Faa7ba4ef-f446-48e3-95e9-0c43d0c3e214.png</url>
      <title>DEV Community: IDRSolutions</title>
      <link>https://dev.to/idrsolutions</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/idrsolutions"/>
    <language>en</language>
    <item>
      <title>How to add a watermark to a PDF in Java (Tutorial)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 10 Jul 2026 08:59:37 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-add-a-watermark-to-a-pdf-in-java-tutorial-1n14</link>
      <guid>https://dev.to/idrsolutions/how-to-add-a-watermark-to-a-pdf-in-java-tutorial-1n14</guid>
      <description>&lt;h2&gt;
  
  
  What is a PDF watermark?
&lt;/h2&gt;

&lt;p&gt;A watermark in a PDF file is a visual element placed behind or over the main content of the page. They are typically faint and translucent. The primary purpose of adding a watermark to a PDF is to convey document status (like “Confidential”) or company branding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Add a Watermark to a PDF Using Java?
&lt;/h2&gt;

&lt;p&gt;If you are building an automated document pipeline, you may want to watermark a PDF using Java to protect your intellectual property. You can programmatically stamp your name or logo so that you can be identified as the owner, or automatically mark unfinished documents with a “Draft” image before they are distributed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Java PDF library should you choose?
&lt;/h2&gt;

&lt;p&gt;When looking to add a watermark to a PDF in Java, there are several options to choose from, each with tradeoffs to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apache PDFBox&lt;/strong&gt; and &lt;strong&gt;iText&lt;/strong&gt; can both add watermarks to PDFs, but they often require low-level handling of content streams and rendering edge cases to work reliably across complex documents. PDFBox is a free Java API, but can struggle with performance and inconsistent rendering. iText provides a more powerful API, but introduces AGPL/commercial licensing constraints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JPedal&lt;/strong&gt; is often preferred for enterprise Java PDF watermarking because its high-fidelity and high-performance engine handles complex PDFs with ease and consistency. It is the perfect tool for batch-processing large volumes of documents.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to watermark a PDF in Java using JPedal
&lt;/h2&gt;

&lt;p&gt;First, &lt;a href="https://www.idrsolutions.com/jpedal/your-trial" rel="noopener noreferrer"&gt;download the JPedal JAR&lt;/a&gt; and then &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/add-jpedal-as-a-maven-dependency" rel="noopener noreferrer"&gt;add it to your project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To make edits to PDF files, you can use JPedal’s &lt;code&gt;PDFManipulator&lt;/code&gt; class. You can &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/pdf-manipulation/pdf-manipulator#how-to-use-the-pdf-manipulator" rel="noopener noreferrer"&gt;learn more about this powerful tool here&lt;/a&gt;. To get started, we will create the basic structure for editing PDF files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PdfManipulator&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PdfManipulator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadDocument&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inputFile.pdf"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// insert operations here…&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reset&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeDocument&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"outputFile.pdf"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;closeDocument&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can add different operations depending on what kind of watermarks we want to add.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Watermark to All PDF Pages
&lt;/h2&gt;

&lt;p&gt;You should rebuild the list of pages each time when loading a document, otherwise a document with more pages than the previous one will not have the watermark applied to the additional pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PageRanges&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PageRanges&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPageCount&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add an Image Watermark to a PDF
&lt;/h2&gt;

&lt;p&gt;To add an image watermark to a PDF:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JDeli&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermark.png"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// X1, Y1, X2, Y2&lt;/span&gt;
&lt;span class="n"&gt;addImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Images may be transparent or in different colour spaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Text Watermark to a PDF
&lt;/h2&gt;

&lt;p&gt;To add a text watermark to a PDF:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.2f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0f&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// RGBA&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BaseFont&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HelveticaBold&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also draw text at an angle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Shape Watermark
&lt;/h2&gt;

&lt;p&gt;To draw a shape onto your PDF:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Rectangle2D&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Float&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;56.7f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;596.64f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;131.53f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;139.25f&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;DrawParameters&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DrawParameters&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStrokeColor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;});&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFillRule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DrawParameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;STROKE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addShape&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Annotations with Watermarks
&lt;/h2&gt;

&lt;p&gt;Annotations by themselves are not suitable for watermarks, as users can easily remove them. However, you could use an annotation to create a clickable hyperlink over your PDF watermarks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAnnotation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFlagsValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// annotation color&lt;/span&gt;
    &lt;span class="mf"&gt;1.0f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// stroking opacity&lt;/span&gt;
    &lt;span class="mf"&gt;1.0f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// fill opacity&lt;/span&gt;
    &lt;span class="s"&gt;"https://www.idrsolutions.com/"&lt;/span&gt;
&lt;span class="o"&gt;));&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Learn more
&lt;/h2&gt;

&lt;p&gt;Looking for a pure Java PDF library to handle processing your documents? &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;Check out JPedal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Want to &lt;a href="https://blog.idrsolutions.com/understanding-the-pdf-file-format/" rel="noopener noreferrer"&gt;learn more about the PDF file format&lt;/a&gt;? We have been developing &lt;a href="https://blog.idrsolutions.com/working-with-pdf-files-in-java/" rel="noopener noreferrer"&gt;PDF software&lt;/a&gt; for over 20 years!&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>java</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to extract JPG data from PDF</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 08 Jul 2026 09:00:48 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-extract-jpg-data-from-pdf-pai</link>
      <guid>https://dev.to/idrsolutions/how-to-extract-jpg-data-from-pdf-pai</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;It is actually possible to extract some raw images from the PDF file. In general, images do not exist inside a PDF file – TIFFs and PNGs are ripped apart and the data stored in separate objects. The data is compressed using various compression formats (JBIG2, CCITT, FLATE, LZW).&lt;/p&gt;

&lt;p&gt;However, one of the formats used for image data is the DCT format. This is actually a JPEG, and if you take the binary data out and save it in a file with a .jpeg format, you can open it. It includes not just the pixel data but also the JPEG header at the start – it is a complete file.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is the JPEG data stored?
&lt;/h2&gt;

&lt;p&gt;If you open a PDF file, the stored JPEG data will appear in the XObject image. Here is an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;14 0 obj
&amp;lt;&amp;lt;
/Intent/RelativeColorimetric
/Type/XObject
/ColorSpace/DeviceGray
/Subtype/Image
/Name/X
/Width 2988
/BitsPerComponent 8
/Length 134030
/Height 2286
/Filter/DCTDecode
&amp;gt;&amp;gt;
stream (binary data) endstream

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Indicators in the PDF Object
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;/Type&lt;/strong&gt; shows that this is an image. The key section is the &lt;strong&gt;/Filter&lt;/strong&gt; value – &lt;strong&gt;DCTDecode&lt;/strong&gt; indicates a JPEG (&lt;strong&gt;JPX&lt;/strong&gt; shows a JPEG2000), which also works.&lt;/p&gt;

&lt;p&gt;The data is between stream and endstream. You need to extract the raw data (cut and paste of text is unlikely to work) for the JPEG file. The **/Length **value shows how long it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Colour Space
&lt;/h2&gt;

&lt;p&gt;Lastly, the &lt;strong&gt;/Colorspace&lt;/strong&gt; is important because it shows the colour-coding used in the JPEG. If it is DeviceRGB, it will look exactly as it is in the PDF display. Not many viewers understand types like DeviceCMYK – you may need a heavyweight package like Photoshop to see it correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes on Clipped Images
&lt;/h2&gt;

&lt;p&gt;If the image is clipped, you may find you can see background details not in the PDF display and the image may also be a different size or even upside down. But you have extracted the raw image data!&lt;/p&gt;

&lt;p&gt;As experienced Java developers, we help you &lt;a href="https://blog.idrsolutions.com/working-with-images-in-java/" rel="noopener noreferrer"&gt;work with images in Java&lt;/a&gt; and bring over a decade of hands-on experience with many image file formats.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>pdf</category>
    </item>
    <item>
      <title>How to redact PDF text with the JPedal Viewer</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 03 Jul 2026 13:44:05 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-redact-pdf-text-with-the-jpedal-viewer-1f9m</link>
      <guid>https://dev.to/idrsolutions/how-to-redact-pdf-text-with-the-jpedal-viewer-1f9m</guid>
      <description>&lt;h2&gt;
  
  
  What is redaction and why should you use it?
&lt;/h2&gt;

&lt;p&gt;Redaction is the process of removing sensitive information from a document so that it is suitable for publishing. It is commonly used in legal or government processes when documents are made available to the public while keeping certain details hidden.&lt;/p&gt;

&lt;p&gt;If you want to publish parts of a document and have certain secrets remain secrets, then redaction is the right tool to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Redaction in PDFs Works
&lt;/h2&gt;

&lt;p&gt;Redaction typically consists of a black rectangle which covers up the text you want hidden. Traditionally, this was done by drawing over text with a black marker and then scanning it back in.&lt;/p&gt;

&lt;p&gt;In the age of digital media, the concept is the same, but care must be taken to ensure that the content is actually removed and cannot be recovered through some sneaky techniques.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitfalls of Weak Digital Redaction Tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One common mistake with low-quality redaction tools is drawing a black box over the text, but leaving the text remaining underneath. Other tools may then allow people to remove the boxes and see the text that was there, or you may just see that large characters like j may poke out of top or bottom of the black box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another mistake is replacing the text with empty characters of the same width. This is done to preserve the layout of subsequent characters, however it is possible to reverse-engineer what text used to be there by looking at the widths of the blank characters and comparing them with the widths from the font. Ideally, any blank spacing should be accumulated so not to leak any information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, a common pitfall to be aware of is that sometimes you can simply figure out what used to be there based on context e.g. “Jane ■■■” appears in one place, but “Jane Doe” appears nearby.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to redact text using the JPedal Viewer
&lt;/h2&gt;

&lt;p&gt;The JPedal Viewer has a tools menu which contains various &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/viewer/manipulate-files-from-the-viewer" rel="noopener noreferrer"&gt;operations you can perform on the currently opened document&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The tools menu is hidden by default, so you will need to enable it by going to edit -&amp;gt; preferences -&amp;gt; menu, and selecting tools.&lt;/p&gt;

&lt;p&gt;Now that the tools menu is visible, you can open a PDF document in the &lt;a href="https://www.idrsolutions.com/jpedal/java-pdf-viewer" rel="noopener noreferrer"&gt;JPedal Viewer&lt;/a&gt;, navigate to the desired page, and select redact from the tools menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdf3mkzzyw26ea3n8tyyl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdf3mkzzyw26ea3n8tyyl.png" alt=" " width="612" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will bring up a dialog box to confirm which page you want to draw over, press OK to confirm.&lt;/p&gt;

&lt;p&gt;You can now drag a rectangle over the area you want to redact. Any text that intersects this rectangle will be removed and a black box will take its place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt02s744fdpioe56sixe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt02s744fdpioe56sixe.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Download JPedal
&lt;/h2&gt;

&lt;p&gt;You can download a copy of &lt;a href="https://www.idrsolutions.com/jpedal/your-trial" rel="noopener noreferrer"&gt;the JPedal jar&lt;/a&gt; from our website and get started using the &lt;a href="https://www.idrsolutions.com/jpedal/java-pdf-viewer" rel="noopener noreferrer"&gt;JPedal Viewer as a PDF redaction tool&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>pdf</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How FormVu Adds Signature Fields to Converted HTML Forms</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 01 Jul 2026 09:15:19 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-formvu-adds-signature-fields-to-converted-html-forms-15g5</link>
      <guid>https://dev.to/idrsolutions/how-formvu-adds-signature-fields-to-converted-html-forms-15g5</guid>
      <description>&lt;h2&gt;
  
  
  Digital Signatures: PDF vs HTML
&lt;/h2&gt;

&lt;p&gt;If you convert PDF forms to HTML, you’ve probably run into the signature problem. Every other HTML form signature field converts cleanly, text inputs, checkboxes, dropdowns, radio buttons all have direct HTML equivalents whereas signature fields don’t. &lt;/p&gt;

&lt;p&gt;The PDF spec ties them to cryptographic infrastructure (certificate chains, byte ranges, PKCS#7 envelopes) that doesn’t exist in a browser. Implementing a digital signature in HTML has always meant bolting something on after the fact. &lt;/p&gt;

&lt;p&gt;Whereas with FormVu’s new feature users don’t need to download the raw PDF, sign it, and upload it back. &lt;a href="https://www.idrsolutions.com/docs/formvu/release-notes/2026-05-release-notes" rel="noopener noreferrer"&gt;FormVu’s May 2026 release&lt;/a&gt; adds a digital signature field to the HTML output. Signature fields in the source PDF now convert to a browser-based signing interface, just like every other form field.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the HTML signature field works
&lt;/h2&gt;

&lt;p&gt;When FormVu encounters a signature field in a source PDF and signing is enabled, the converted HTML includes an HTML electronic signature input at the same position in the form. The interface gives users three ways to sign:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Draw a signature directly in the browser&lt;/li&gt;
&lt;li&gt;Upload an image of their signature&lt;/li&gt;
&lt;li&gt;Type their name as text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No additional JavaScript libraries, no manual integration per form.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling the signature field in HTML output
&lt;/h2&gt;

&lt;p&gt;No need to write electronic signature HTML code yourself. The feature is controlled by a single JVM flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-Dorg.jpedal.pdf2html.useFormVuSigning=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via the Java API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;FormViewerOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormViewerOptions&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUseFormVuSigning&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set it to &lt;code&gt;true&lt;/code&gt; and signature fields in the source PDF will convert to the signing interface. Set it to &lt;code&gt;false&lt;/code&gt; (or omit it) and you get the previous behavior, signature fields render as empty space. You can find the Javadoc for FormVu digital signing &lt;a href="https://files.idrsolutions.com/maven/site/formvu/apidocs/org/jpedal/render/output/FormViewerOptions.html#setUseFormVuSigning(boolean)" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is (and what it isn’t)
&lt;/h2&gt;

&lt;p&gt;FormVu’s signature feature is visual image-based signing, not &lt;a href="https://blog.idrsolutions.com/digital-signatures-in-a-pdf/" rel="noopener noreferrer"&gt;cryptographic signing&lt;/a&gt;. The user draws, uploads, or types a signature, and that image is placed on the signature field. There’s no certificate embedding, no hash validation, no PKCS#7 envelope generated in the browser. &lt;/p&gt;

&lt;p&gt;This approach works better for converter HTML forms since you’re outside the PDF signing infrastructure when signing. The browser captures the signature input, storing it, embedding it back into a PDF. If you need cryptographic signatures applied to the original PDF document, use &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal&lt;/a&gt; directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for PDF-to-HTML conversion
&lt;/h2&gt;

&lt;p&gt;Signature fields were a major form field type that FormVu couldn’t convert before. For teams in insurance, government, healthcare, or compliance, where forms almost always require a signature, this was the gap that kept them serving raw PDFs or maintaining custom workarounds for every converted form. &lt;/p&gt;

&lt;p&gt;That constraint is gone. With &lt;code&gt;useFormVuSigning&lt;/code&gt; enabled, every signature field in the HTML form works. One flag, no per-form integration work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version and compatibility
&lt;/h2&gt;

&lt;p&gt;Available in the May 2026 release of &lt;a href="https://www.idrsolutions.com/formvu/" rel="noopener noreferrer"&gt;FormVu&lt;/a&gt;. There are no changes needed to your existing conversion pipeline beyond setting the JVM flag. The generated signature interface works in all current browsers.&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>PDF to HTML5 conversion – No Even-Odd Winding Rule for filling shapes in HTML5? – Part 2</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 26 Jun 2026 11:20:07 +0000</pubDate>
      <link>https://dev.to/idrsolutions/pdf-to-html5-conversion-no-even-odd-winding-rule-for-filling-shapes-in-html5-part-2-4age</link>
      <guid>https://dev.to/idrsolutions/pdf-to-html5-conversion-no-even-odd-winding-rule-for-filling-shapes-in-html5-part-2-4age</guid>
      <description>&lt;p&gt;This is part 2 of this subject. If you haven’t already read it, please read part &lt;a href="https://dev.to/idrsolutions/pdf-to-html5-conversion-no-even-odd-winding-rule-for-filling-shapes-in-html5-part-1-5hbn"&gt;1&lt;/a&gt; to understand the winding problem.&lt;/p&gt;

&lt;p&gt;So to recap quickly: HTML5 only supports the Non-Zero winding rule, PDF supports both Non-Zero and Even-Odd rules. This means that we need to do something with shapes filled using the Even-Odd rule; they may not display correctly.&lt;/p&gt;

&lt;p&gt;To demonstrate in this blog article, I will be using this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwpfjhm5twzunlylao47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwpfjhm5twzunlylao47.png" alt=" " width="203" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just a red circle? The first time I saw it, that was my thought too. It’s only after changing the fill to a stroke that you realise what it actually is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzutiqof52e1uv5vpdjen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzutiqof52e1uv5vpdjen.png" alt=" " width="200" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To help understand what’s going on, here it is with arrows showing the directions of the paths shown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fatmmeg28v27edqggq33g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fatmmeg28v27edqggq33g.png" alt=" " width="200" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So our first thought was that we needed to make some kind of change to the way that we draw the shape. The obvious thing was to change the direction of some of the paths drawn in order to “convert” it from Even-Odd to Non-Zero.&lt;/p&gt;

&lt;p&gt;Would alternating between clockwise and anti-clockwise work? Well, it was worth a try just to see what the effect was. And besides, it will only take a minute anyway.&lt;/p&gt;

&lt;p&gt;Well, it turns out that it’s actually a bit of a headache. It’s fine if you are doing something simple, like just using lineTo to draw a box, but with bezier curves, it’s not quite so easy.&lt;/p&gt;

&lt;p&gt;If you were to just reverse the order of the draw commands, you get something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi9df30b9vufl4jly4dil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi9df30b9vufl4jly4dil.png" alt=" " width="191" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The order of the two control points makes a difference to the way that the curve is drawn. So what about reversing the order of the control points for the lines, too?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj2jsxz24btsdxq27r2wg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj2jsxz24btsdxq27r2wg.png" alt=" " width="189" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh, that doesn’t quite seem right either. The type of bezier curve used is a bezierCurveTo, which means that it takes our current position (where we ended up from the previous command), and draws a curve to a position that we specify using two control points. &lt;/p&gt;

&lt;p&gt;What that means is that we need to step back to position backwards so that each command uses the position of the last command, so that our control points draw our curve correctly.&lt;/p&gt;

&lt;p&gt;Good. So we can reverse the direction of the path so that our image draws correctly:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq0wwe3izofa8v17q2i59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq0wwe3izofa8v17q2i59.png" alt=" " width="190" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So are we done? No. While doing something like this may be OK for our no-entry sign, where we can control the order and direction of the shapes that get drawn, this approach is no good for a general case. &lt;/p&gt;

&lt;p&gt;In the real world, we can’t just program for specific cases; we need to program for a general case so that our code works for any PDF file, not just the ones we’ve seen before.&lt;/p&gt;

&lt;p&gt;And this means that doing something like alternating the direction between paths is not going to work. Here’s how it would look for our no-entry sign:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4y80ptzbf4q8zkhz6ma0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4y80ptzbf4q8zkhz6ma0.png" alt=" " width="189" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My next thought was that we could just fill the overlapping shapes with the background colour. But this wouldn’t work either because again, the order is important. &lt;/p&gt;

&lt;p&gt;Even if we were to fill our two D’s with white, when we draw and fill the circle around them, it’s just going to cover up all of our hard work. It would also be no good for shapes that only partially overlap each other, because only the intersection of the two would need to be unfilled. &lt;/p&gt;

&lt;p&gt;And it’s also important to remember that the unfilled pieces are just that – unfilled. By filling them with a background colour, you lose transparency, which means we wouldn’t be able to put anything behind our no entry sign to say you’re not allowed to do it.&lt;/p&gt;

&lt;p&gt;So what now? If we can’t draw the shapes in a different order, and we can’t change the direction that some of the shapes are drawn, and we can’t fill in different pieces to create the illusion that we have fixed the problem, how else can we alter our shape so that it magically works using the Non-Zero winding rule?&lt;/p&gt;

&lt;p&gt;We could get really clever and do some really complicated stuff and somehow cut our combined shape into lots of smaller shapes so that we can detect how it should be drawn, and then fill the smaller shapes accordingly.&lt;/p&gt;

&lt;p&gt;A bit like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffcmrwzafn6ew72cztdd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffcmrwzafn6ew72cztdd9.png" alt=" " width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that’s a little overkill for what we want. After all, it might not even matter that the shape we are drawing is drawn using Non-Zero rather than Even-Odd. And that’s a lot of computation time that will just be wasted, resulting in poor performance for our converter. And besides, I am nowhere near clever enough to be able to code that up.&lt;/p&gt;

&lt;p&gt;Since I started playing with these shapes, there has been a niggling thought at the back of my mind. What if we were just to output these shapes as images and be done with it?&lt;/p&gt;

&lt;p&gt;This would work just fine, but it is not optimal. Very rarely is there a shape drawn where the output from using either the Non-Zero or Even-Odd rule is actually different. So, outputting as an image every time a shape is drawn using the Even-Odd rule is going to output lots of images that are not actually required.&lt;/p&gt;

&lt;p&gt;And this is no fun because shapes are nice. They scale beautifully, take no time at all to convert from PDF to HTML5, and take up barely any space at all compared to an image.&lt;/p&gt;

&lt;p&gt;But what other option is there? Unfortunately, we are left with a compromise. The best we can do is create some criteria that the shape must pass before we output it as an image.&lt;/p&gt;

</description>
      <category>html</category>
      <category>pdf</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Save Java images as Tifs with JAI</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 24 Jun 2026 09:54:07 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-save-java-images-as-tifs-with-jai-386f</link>
      <guid>https://dev.to/idrsolutions/how-to-save-java-images-as-tifs-with-jai-386f</guid>
      <description>&lt;p&gt;Java makes it very easy to create images as BufferedImages which  can then be saved out in standard image file formats. Here is the code to save an image as a Tif image using the JAI image (a free library from Sun).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;codec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TIFFEncodeParam&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;codec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TIFFEncodeParam&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;FileOutputStream&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileOutputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputDir&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;imageName&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tif&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;javax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;JAI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="no"&gt;TIFF&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works very nicely but there are a number of extra tricks worth knowing.&lt;/p&gt;

&lt;p&gt;Firstly, there is a compression option available to compress the image – use the modified code as shown below. There are several types of compression but several of them produce Tif files which will not display under Windows or Mac – COMPRESSION_PACKBITS works well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;codec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TIFFEncodeParam&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;codec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TIFFEncodeParam&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCompression&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;media&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;codec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TIFFEncodeParam&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;COMPRESSION_PACKBITS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondly, the type of image you save out can have a huge effect on the size of the Tif image. If you save a grayscale image, it produces a much smaller file and also compresses much better than an RGB or ARGB image. &lt;/p&gt;

&lt;p&gt;You can find out the image type by using image.getType() – the int values returned are all static Constants in the BufferedImage class.&lt;/p&gt;

&lt;p&gt;You can convert the image to another format by creating a second BufferedImage in that format and drawing the original image onto it. Here is the code to make any image grayscale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;image_to_save2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_to_save&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWidth&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;&lt;span class="n"&gt;image_to_save&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeight&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;BufferedImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_BYTE_GRAY&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;image_to_save2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getGraphics&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;drawImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_to_save&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;image_to_save&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_to_save2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For our PDF library, we always generate images in ARGB (we need to because PDF files can have transparency which only works in ARGB). But sometimes the image is only grayscale. Using both these tricks of converting to grayscale and compressing allowed us to reduce the size of the Tif files created from a sample PDF file from 1.4 Meg to 52K – pretty impressive!&lt;/p&gt;

&lt;p&gt;As experienced Java developers, we help you &lt;a href="https://blog.idrsolutions.com/working-with-images-in-java/" rel="noopener noreferrer"&gt;work with images in Java&lt;/a&gt; and bring over a decade of hands-on experience with many image file formats.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>jai</category>
    </item>
    <item>
      <title>How to remove text from a PDF in Java using JPedal (Tutorial)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 19 Jun 2026 08:56:21 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-remove-text-from-a-pdf-in-java-using-jpedal-tutorial-43km</link>
      <guid>https://dev.to/idrsolutions/how-to-remove-text-from-a-pdf-in-java-using-jpedal-tutorial-43km</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnpkpx1rzajdnqmww6qpj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnpkpx1rzajdnqmww6qpj.png" alt=" " width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why remove text from a PDF file?
&lt;/h2&gt;

&lt;p&gt;Removing text from a PDF in Java is a common requirement when dealing with sensitive information, names, email addresses, phone numbers, and other personally identifiable information. &lt;/p&gt;

&lt;p&gt;Whether you are meeting GDPR redaction obligations, preparing documents for external sharing, or sanitising files before archiving, this tutorial explains how to do it using the &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal PDF library&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What redaction actually means
&lt;/h2&gt;

&lt;p&gt;Removing text from a PDF is a two-part problem. First, you find the text. Then you redact it, which itself has two layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hide the text visually, usually done by drawing an opaque box over it&lt;/li&gt;
&lt;li&gt;Remove it from the underlying content stream so it cannot be extracted by a PDF reader or copy-paste&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both steps are critical. Drawing a black box without editing the content stream is not true redaction. The text is still there, just invisible, and people will be able to copy and paste it. JPedal handles both steps, and together these are called redaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a Java PDF library for text removal
&lt;/h2&gt;

&lt;p&gt;Most developers reach for Apache PDFBox first, but programmatically removing text from a PDF in Java, rather than just drawing over it, requires direct access to the content stream. JPedal exposes this through a clean API, handling both the search and the redaction in a few lines of code without manual stream manipulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find, delete and redact text from a PDF in Java using JPedal
&lt;/h2&gt;

&lt;p&gt;Open the PDF, scan each page for the target text, redact every match, then write out the modified document. The key methods are &lt;code&gt;findTextOnPage()&lt;/code&gt; to locate matches and &lt;code&gt;redact()&lt;/code&gt; to remove them. &lt;code&gt;pdf.apply()&lt;/code&gt; commits the redaction operations to the document before writing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.idrsolutions.com/jpedal/#why-buy" rel="noopener noreferrer"&gt;Download JPedal trial jar&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Create a File handle to the PDF file&lt;/li&gt;
&lt;li&gt;Include a password if file password protected&lt;/li&gt;
&lt;li&gt;Open the PDF file&lt;/li&gt;
&lt;li&gt;Scan the pages for text&lt;/li&gt;
&lt;li&gt;Redact each match&lt;/li&gt;
&lt;li&gt;Write the output and close
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final File inputFile = new File("inputFile.pdf");
final FindTextInRectangle extract = new FindTextInRectangle(inputFile);
final PdfManipulator pdf = new PdfManipulator();
pdf.loadDocument(inputFile);
if (extract.openPDFFile()) {
    final int pageCount = extract.getPageCount();
    for (int page = 1; page &amp;lt;= pageCount; page++) {
        final float[] coords = extract.findTextOnPage(page, "the", SearchType.MUTLI_LINE_RESULTS);
        for (int val = 0; val &amp;lt; coords.length; val = val + 5) {
            pdf.redact(page, new float[] {coords[val], coords[val + 1], coords[val + 2], coords[val + 3]});
        }
    }
}
extract.closePDFfile();
//apply changes and write out
pdf.apply();
final File outputFile = new File("redactedFile.pdf");
pdf.writeDocument(outputFile);
pdf.closeDocument();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;findTextOnPage()&lt;/code&gt; returns a flat float array of coordinates for each match, x1, y1, x2, y2, plus a fifth value (magic number documented &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/search/find-text-in-a-pdf-file" rel="noopener noreferrer"&gt;here&lt;/a&gt;) at index 4, which is why the loop increments by 5. The output is a new PDF with every instance of the search term permanently removed from both the visual layer and the content stream.&lt;/p&gt;

&lt;p&gt;The original file is not modified unless you overwrite it. Add try-catch blocks around the file operations and PDF calls for production use. For other PDF text manipulation tasks in Java, extracting, searching, or modifying content programmatically, see the &lt;a href="https://www.idrsolutions.com/docs/jpedal/" rel="noopener noreferrer"&gt;JPedal tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can expand your &lt;a href="https://blog.idrsolutions.com/understanding-the-pdf-file-format/" rel="noopener noreferrer"&gt;understanding of the PDF format&lt;/a&gt; by reading our other articles. Similarly, if there is a specific term for PDF you would like to know more about, our &lt;a href="https://blog.idrsolutions.com/glossary-of-pdf-terms/" rel="noopener noreferrer"&gt;PDF Glossary&lt;/a&gt; has an extensive list of common terms.&lt;/p&gt;

</description>
      <category>java</category>
      <category>pdf</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to draw PDF XFA Forms accurately (in your viewer)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 17 Jun 2026 09:58:16 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-draw-pdf-xfa-forms-accurately-in-your-viewer-49p0</link>
      <guid>https://dev.to/idrsolutions/how-to-draw-pdf-xfa-forms-accurately-in-your-viewer-49p0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It is a bit of a complex task if any attempt is made to try and display XFA forms (by following the XFA specification) in a custom viewer rather than the Adobe life cycle. Either you are expected to have a similar functionality to the HTML parser, which should be intelligent enough to draw components recursively, or you should have a custom parser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure of Subforms
&lt;/h2&gt;

&lt;p&gt;Subforms in XFA may contain one or many subforms, and each of them may contain individual components that could be either containers (containing subforms, exclusion groups, area, subformset) or widgets (Rectangle, text, arc, input text, checkbox, choice-list and so on).&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Coordinates and Dimensions
&lt;/h2&gt;

&lt;p&gt;Every subform’s x,y coordinates depend on previous and parent elements of it; its height depends on the height and width of the child elements if the H attribute or min H attribute is not specified.&lt;/p&gt;

&lt;p&gt;In such a complex situation, the form height and x,y coordinates should be in memory or should be injected as an attribute in order to render them accurately (in my personal opinion, injecting data as an attribute consume much less memory).&lt;/p&gt;

&lt;h2&gt;
  
  
  Influence of Datasets
&lt;/h2&gt;

&lt;p&gt;Datasets also have a major influence on the way the form is rendered, because form occurrences (number of forms) have to be multiplied based on bind data (be aware that bind names play a major role rather than the typical name attribute of the subform node).&lt;/p&gt;

&lt;h2&gt;
  
  
  Page Breaks and Content Overflow
&lt;/h2&gt;

&lt;p&gt;Forms do have page breaks that render the form and its components on different pages. In addition to that, components of a single form can be split into multiple pages if their x,y location exceeds the allowed height of the content area of the PageArea element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended Handling Approach
&lt;/h2&gt;

&lt;p&gt;One of the recommended ways of handling such a scenario described above is to draw the form coordination in memory or as attributes and splitting them later based on page breaks, data sets and content area overflow. Margins (left, right, bottom and top) also need to be considered on the stage of rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layout Considerations
&lt;/h2&gt;

&lt;p&gt;Possible subform layouts such as Positioned, Top to bottom. Left to right, right to left, table and row have to be considered in finding the relevant heights of the given subform. The calculation may vary from one to another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic XFA Forms and JavaScript
&lt;/h2&gt;

&lt;p&gt;Dynamic XFA forms contain JavaScript (a real beast in XFA layout)  that determines visibility and total occurrence of individual forms.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>html</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>PDF to HTML5 conversion – No Even-Odd Winding Rule for filling shapes in HTML5? – Part 1</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 12 Jun 2026 09:55:29 +0000</pubDate>
      <link>https://dev.to/idrsolutions/pdf-to-html5-conversion-no-even-odd-winding-rule-for-filling-shapes-in-html5-part-1-5hbn</link>
      <guid>https://dev.to/idrsolutions/pdf-to-html5-conversion-no-even-odd-winding-rule-for-filling-shapes-in-html5-part-1-5hbn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When filling shapes in PDFs (and lots of other technologies) you get a choice between using the Even-Odd or the Non-Zero winding rule.&lt;/p&gt;

&lt;p&gt;For those of you already thinking to yourself “what the hell is he talking about?” – don’t worry, I shall explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Shape Filling
&lt;/h2&gt;

&lt;p&gt;A shape has an inside and an outside, and what is the inside and what is the outside is quite simple to work out, given that it is a simple shape. But what if you scribble over a page crossing over your paths several times to eventually join up where you started – what is the inside and what is the outside of this shape? And what about if you have nested shapes, or shapes that cover each other?&lt;/p&gt;

&lt;p&gt;We can solve this problem by using the Even-Odd rule or the Non-Zero rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Even-Odd Rule
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Even-Odd:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This rule determines the “insideness” of a point on the canvas by drawing a ray from that point to infinity in any direction and counting the number of path segments from the given shape that the ray crosses. If this number is odd, the point is inside; if even, the point is outside.”&lt;br&gt;
  – &lt;a href="http://www.w3.org/TR/SVG/painting.html#FillProperties" rel="noopener noreferrer"&gt;w3C SVG&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To illustrate:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F593hgaeu4s12h7ktxgm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F593hgaeu4s12h7ktxgm3.png" alt="Even odd rule SVG" width="634" height="205"&gt;&lt;/a&gt;&lt;br&gt;
(Reference &lt;a href="http://www.w3.org/TR/SVG/painting.html#FillProperties" rel="noopener noreferrer"&gt;w3C SVG 1.1&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Non-Zero Winding Rule
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Non-Zero:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This rule determines the “insideness” of a point on the canvas by drawing a ray from that point to infinity in any direction and then examining the places where a segment of the shape crosses the ray. Starting with a count of zero, add one each time a path segment crosses the ray from left to right and subtract one each time a path segment crosses the ray from right to left. After counting the crossings, if the result is zero then the point is outside the path. Otherwise, it is inside.”&lt;br&gt;
 &lt;a href="http://www.w3.org/TR/SVG/painting.html#FillProperties" rel="noopener noreferrer"&gt;w3C SVG 1.1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To illustrate:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9tf4joaq1g6o1ri0wr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9tf4joaq1g6o1ri0wr7.png" alt="Zero Winding rule SVG" width="634" height="211"&gt;&lt;/a&gt;&lt;br&gt;
(Reference &lt;a href="http://www.w3.org/TR/SVG/painting.html#FillProperties" rel="noopener noreferrer"&gt;w3C SVG 1.1&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Key Difference
&lt;/h2&gt;

&lt;p&gt;So to put it simply – when using the Non-Zero Winding Rule, the direction in which you draw the shapes matters. And if you try to draw a shape that is meant to use the Even-Odd rule instead of using the Non-Zero rule, you are going to end up with areas filled that should not be filled.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem in PDF to HTML5 Conversion
&lt;/h2&gt;

&lt;p&gt;And this becomes a problem when you are trying to convert from PDF (which supports both rules) to HTML5 which only supports the Non-Zero winding rule.&lt;/p&gt;

&lt;p&gt;So this leaves us with a dilemma – what do we do with PDF shapes that use the Even-Odd rule when we convert the PDF to HTML5?&lt;/p&gt;

&lt;p&gt;To find out, Part 2 of this blog article can be found &lt;a href="https://blog.idrsolutions.com/pdf-to-html5-conversion-no-even-odd-winding-rule-for-filling-shapes-in-html5-part-2/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>html</category>
      <category>pdf</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Odd coloured JPEGs in Java with ImageIO</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 10 Jun 2026 08:41:38 +0000</pubDate>
      <link>https://dev.to/idrsolutions/odd-coloured-jpegs-in-java-with-imageio-5al7</link>
      <guid>https://dev.to/idrsolutions/odd-coloured-jpegs-in-java-with-imageio-5al7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of the best features about Java is the amount of low-level complexity it removes, allowing you to focus on developing the application. However, this does sometimes hide some important issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Issue with ImageIO
&lt;/h2&gt;

&lt;p&gt;We found one of these with the ImageIO class which offers a whole series of methods to save an image as a Tiff, a PNG or a JPEG. All the complexity is hidden and you can save out the image in one line of code (magic). Unfortunately, it also hides an interesting feature…&lt;/p&gt;

&lt;h2&gt;
  
  
  Transparency and JPEGs
&lt;/h2&gt;

&lt;p&gt;ImageIO will happily save all kinds of images, including images with transparency (ARGB). And it will save it as a JPEG, even though JPEGs do not really support transparency. The problem comes when you try to view the JPEG. Java understands this hybrid image so it will load back correctly, but very few other tools do.&lt;/p&gt;

&lt;p&gt;Because it has 4 bands (RGB are three and then transparency makes the fourth), most JPEG tools assume it must be in the CMYK colorspace and interpret the colours as CMYK. CMYK works completely differently to RGB so the image comes out looking wrong (often with a nasty red tint). Unfortunately, there is no way that a JPEG Decoder can spot this has happened – it is a bug in the way  ImageIO works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Fix: Removing the Alpha Component
&lt;/h2&gt;

&lt;p&gt;You can manually fix it by removing any alpha component from your BufferedImage before you save it in ImageIO with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="nf"&gt;convertARGBToRGB&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pixels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nc"&gt;DataBufferInt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRaster&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getDataBuffer&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;getData&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWidth&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeight&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;BufferedImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_INT_RGB&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pixelsOut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nc"&gt;DataBufferInt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRaster&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getDataBuffer&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;getData&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;arraycopy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pixels&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixelsOut&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixels&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JDeli: A Better Alternative
&lt;/h2&gt;

&lt;p&gt;JDeli is the best enterprise-level Java image library for performance and efficiency. In our &lt;a href="https://www.idrsolutions.com/jdeli/" rel="noopener noreferrer"&gt;JDeli image library&lt;/a&gt; (which provides a complete &lt;a href="https://www.idrsolutions.com/docs/jdeli/tutorials/converting/jpg-converter" rel="noopener noreferrer"&gt;JPG Converter&lt;/a&gt;), we have actually added a flag to read the JPEG correctly for you if you know the file is broken.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="nc"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
 &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DECODE_4_COMPONENTS_AS_ARGB"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"TRUE"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JDeli&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jpeg&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// Deal with read error here.&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So while Java makes life much easier most of the time, there are some interesting gotchas out there…&lt;/p&gt;

&lt;p&gt;As experienced Java developers, we help you &lt;a href="https://blog.idrsolutions.com/working-with-images-in-java/" rel="noopener noreferrer"&gt;work with images in Java&lt;/a&gt; and bring over a decade of hands-on experience with many image file formats.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why choose a pure Java PDF library?</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 05 Jun 2026 12:45:37 +0000</pubDate>
      <link>https://dev.to/idrsolutions/why-choose-a-pure-java-pdf-library-lgh</link>
      <guid>https://dev.to/idrsolutions/why-choose-a-pure-java-pdf-library-lgh</guid>
      <description>&lt;h2&gt;
  
  
  What are the benefits of a pure Java PDF library and why does it matter?
&lt;/h2&gt;

&lt;p&gt;PDF processing sits at the core of many enterprise systems, and the Java PDF library you choose to build your system have significant implications.&lt;br&gt;
If you are building a new system then here is why you should choose a pure Java PDF library.&lt;/p&gt;

&lt;p&gt;Whether you are selecting a PDF generation library in Java, for high-volume document creation, evaluating a Java PDF editor library for annotation workflows or integrating a Java PDF API into an existing microservice, the pure Java constraint narrows the field considerably, and for good reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write once, run anywhere
&lt;/h2&gt;

&lt;p&gt;Java’s slogan “write once, run anywhere” is particularly valuable in PDF processing. A pure Java library runs on any platform/operating system which removes the need for recompilation or platform-specific code. &lt;/p&gt;

&lt;p&gt;You can deploy the same code that you wrote on your MacBook to a Linux or Windows server. This effectively removes any concerns for environment-specific bugs or cross-platform issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplified distribution and deployment
&lt;/h2&gt;

&lt;p&gt;With a pure Java solution, the burden of managing different native binaries compiled for different architectures does not exist. You no longer need to maintain multiple builds for x86 or ARM. &lt;/p&gt;

&lt;p&gt;This makes distribution much simpler, especially if you are shipping to end users. If deploying to the cloud then you only need to create a single container image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved security and stability
&lt;/h2&gt;

&lt;p&gt;Security is a critical concern in PDF processing. The PDF file format is very complex and has been a frequent target for vulnerabilities and exploits. This is especially common in native libraries written in low level code. (&lt;a href="https://en.wikipedia.org/wiki/FORCEDENTRY" rel="noopener noreferrer"&gt;See this scary example!&lt;/a&gt;). Running code entirely within the JVM introduces a strong safety layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory management is handled automatically by the garbage collection, reducing risks like buffer overflow exploits&lt;/li&gt;
&lt;li&gt;There is no direct memory access which removes the risk of segmentation faults or other similar memory corruption errors&lt;/li&gt;
&lt;li&gt;Java’s security model ensures that execution is isolated and controlled&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Easier debugging and maintenance
&lt;/h2&gt;

&lt;p&gt;Java has a very mature ecosystem of development tools, including debuggers, profilers and refactoring utilities which are widely available and well integrated into modern IDEs. This has several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify and resolve issues faster&lt;/li&gt;
&lt;li&gt;Easier to maintain codebase&lt;/li&gt;
&lt;li&gt;More efficient refactoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast, debugging native code involves more complex tooling and can pose some platform-specific challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simpler licensing
&lt;/h2&gt;

&lt;p&gt;When a library has no external dependencies it makes the licensing very straightforward. This can reduce the legal complexity of procurement and lowers the risk of compliance issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, choosing a pure Java PDF library can be a strategic decision. By leveraging Java’s portability, security and ecosystem, enterprises can create large systems with much less technical debt in the long term. In the intricate field of PDF processing, this reduced complexity pays dividends across the entire software lifecycle.&lt;/p&gt;

&lt;p&gt;The table below outlines the differences between a pure Java PDF SDK versus one that was written using native code and Java:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10hjb8dyiwx3s0hblr6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10hjb8dyiwx3s0hblr6o.png" alt="Pure vs Native Java PDF library" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Looking for a pure Java PDF library to handle processing your documents? Check out &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Want to &lt;a href="https://blog.idrsolutions.com/understanding-the-pdf-file-format/" rel="noopener noreferrer"&gt;learn more about the PDF file format?&lt;/a&gt; We have been developing PDF software for over 20 years!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>pdf</category>
      <category>programming</category>
    </item>
    <item>
      <title>Dynamic XFA/PDF to HTML – resolveNode method</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 03 Jun 2026 09:11:39 +0000</pubDate>
      <link>https://dev.to/idrsolutions/dynamic-xfapdf-to-html-resolvenode-method-2630</link>
      <guid>https://dev.to/idrsolutions/dynamic-xfapdf-to-html-resolvenode-method-2630</guid>
      <description>&lt;p&gt;Dynamic XFA forms contain JavaScript which needs some considerable tidying up to convert into content which will run on a Browser.&lt;/p&gt;

&lt;p&gt;In this technical article, our lead developer of FormVu (which converts Acrobat forms into standalone HTML5) gives you an insight into some of the technical issues involved. FormVu is the best tool for filling PDF forms in HTML.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://files.idrsolutions.com/Examples/XFAForms/Purchase_Order_Blank/form.html" rel="noopener noreferrer"&gt;An XFA form with an example of resolveNode.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article I do an overview of some factors that have to be taken into consideration prior to implementing resolveNode subroutine in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why resolveNode?
&lt;/h2&gt;

&lt;p&gt;Adobe lifecycle designer follows the Ecma Script 357 specification to represent the SOM model structure.&lt;/p&gt;

&lt;p&gt;In a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;class&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;student&amp;gt;&amp;lt;name&amp;gt;&lt;/span&gt;john&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&amp;lt;/student&amp;gt;&lt;/span&gt;.

&lt;span class="nt"&gt;&amp;lt;student&amp;gt;&amp;lt;name&amp;gt;&lt;/span&gt;david&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&amp;lt;/student&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/class&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to access the name of the second student, then you need to pass the query as “class.student[1].name” for access&lt;/p&gt;

&lt;p&gt;But such an array-based access algorithm is not available in regular JavaScript; therefore, the resolveNode method is implemented to reference the node information from an ECMAScript 357-supported script.&lt;/p&gt;

&lt;p&gt;ResolveNode method plays a major role in adding, removing, and moving subform instances on the fly:&lt;/p&gt;

&lt;p&gt;A nice html implementation example of this functionality can be found &lt;a href="https://files.idrsolutions.com/Examples/XFAForms/Purchase_Order_Blank/form.html" rel="noopener noreferrer"&gt;in this converted example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have a go at trying to add and delete items from purchase order form.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to handle resolveNode function:
&lt;/h2&gt;

&lt;p&gt;The following are steps that simplify the process of handling resolveNode functions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Write down the short representation of your full XFA form model by removing the internal node structure of fields, so you can track the method insertion point and the caller of the function very quickly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always use descendant search prior to ascendant search: if you do not find the required item in descendants, then move to the ascendant nodes;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use parent-by-parent search while traversing to ascendant nodes:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check for [*] symbol: if you come across this sign, try to traverse through all the nodes that have the same named descendants of the particular node;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check for “..” symbol for descendant search and “.parent” for accessing the parent node.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can see, it can be done but requires a large amount of pre-processing.&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>pdf</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
