<?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>iOS and HTML5: Gotcha with Absolute Positioning</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 29 Jul 2026 08:52:21 +0000</pubDate>
      <link>https://dev.to/idrsolutions/ios-and-html5-gotcha-with-absolute-positioning-2gla</link>
      <guid>https://dev.to/idrsolutions/ios-and-html5-gotcha-with-absolute-positioning-2gla</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of the aims of &lt;a href="https://www.idrsolutions.com/buildvu/" rel="noopener noreferrer"&gt;BuildVu&lt;/a&gt; and all of its various view modes (all 9 of them) was to make viewing of PDF files easy and platform-independent, where the user only needs a relatively modern web browser to view them.&lt;/p&gt;

&lt;p&gt;And as we designed the output to be used by the browser, we also allow you to select and search the text using your browser’s default tools, and this free functionality normally works great in all web browsers, across all platforms, even Android devices, as you can see in the images in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue on iOS Browsers
&lt;/h2&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%2F3zczqqw1jhxmlrf4xtmy.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%2F3zczqqw1jhxmlrf4xtmy.png" alt="ios browser screen grab" width="800" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this sadly isn’t true within Apple’s current version of Safari on iOS and Chrome on iOS. Currently, both don’t quite support all the latest CSS to as great a degree as other mobile devices, and as a result of its bizarre Selection engine, it’s very difficult and often impossible to select text on pages containing complicated CSS (explained below).&lt;/p&gt;

&lt;p&gt;We recently had a customer query us about why they couldn’t select the text of our output on their iPad, which struck us as an odd question; the default mode for our output has had selectable text for as long as I can recall so my initial thought was that it may have just been a user unfamiliar with how to select text on an iPad. However, we still checked to be sure and were surprised to find that the text wasn’t selectable.&lt;/p&gt;

&lt;p&gt;This was puzzling because, as I mentioned before, the text has always been selectable, it is, after all, just text within a div tag in the HTML, and we were sure it worked previously.&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%2F5hq27qw36ydhxi2hk19j.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%2F5hq27qw36ydhxi2hk19j.png" alt="ios browser screenshot" width="800" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Investigating the Problem
&lt;/h2&gt;

&lt;p&gt;After going over our current output, I found some older output that worked and had a look at the differences to the current version.&lt;/p&gt;

&lt;p&gt;Visually they looked almost identical, with a few improvements in regard to character spacing in our current version and a different background colour.&lt;/p&gt;

&lt;p&gt;Structurally, the newer version differs quite a lot from the older version. In our older versions, we placed the text within div tags under our parent jpedal tag with styling like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body style="background-color: rgb(55,55,65);"&amp;gt;
&amp;lt;div id="jpedal" style="position:relative; width: 984px; margin: 0 auto;"&amp;gt;
&amp;lt;!– Shared CSS values –&amp;gt;
&amp;lt;style type="text/css" &amp;gt;
.t {
position:absolute;
white-space:nowrap;
overflow:visible;
z-index:1;
}
.tr {
-webkit-transform-origin: left top;
-ms-transform-origin: left top;
-moz-transform-origin: left top;
-o-transform-origin: left top;
}
&amp;lt;/style&amp;gt;
&amp;lt;!– Inline CSS values –&amp;gt;
&amp;lt;style type="text/css" &amp;gt;
#t1_1 {
left:90px;
top:60px;
FONT-SIZE: 60px;
FONT-FAMILY: CataneoBT-Regular1;
color:rgb(0,85,149);
}
#t2_1 {
-webkit-transform:matrix(0.97,0,-0.2,0.97,114, 181);
-ms-transform:matrix(0.97,0,-0.2,0.97,114, 181);
-moz-transform:matrix(0.97,0,-0.2,0.97,114, 181);
-o-transform:matrix(0.97,0,-0.2,0.97,114, 181);
FONT-SIZE: 21px;
FONT-FAMILY: IGNACK-RaleighBT-Roman1;
color:rgb(35,32,32);
}
#t3_1 {
-webkit-transform:matrix(0.97,0,-0.2,0.97,350, 212);
-ms-transform:matrix(0.97,0,-0.2,0.97,350, 212);
-moz-transform:matrix(0.97,0,-0.2,0.97,350, 212);
-o-transform:matrix(0.97,0,-0.2,0.97,350, 212);
FONT-SIZE: 13px;
FONT-FAMILY: IGNACK-RaleighBT-Roman1;
color:rgb(35,32,32);
}
&amp;lt;/style&amp;gt;
&amp;lt;!– Any embedded fonts defined here –&amp;gt;
&amp;lt;style type="text/css" &amp;gt;
@font-face {
font-family: CataneoBT-Regular1;
src: url("01/fonts/CataneoBT-Regular.woff");
}
@font-face {
font-family: IGNACK-RaleighBT-Roman1;
src: url("01/fonts/IGNACK-RaleighBT-Roman.woff");
}
&amp;lt;/style&amp;gt;
&amp;lt;!– Text defined here and setup in CSS –&amp;gt;
&amp;lt;div id="t1_1″ class="t"&amp;gt;Some things never change&amp;lt;/div&amp;gt;
&amp;lt;div id="t2_1″ class="t tr"&amp;gt;Never trust a dog to watch your food.&amp;lt;/div&amp;gt;
&amp;lt;div id="t3_1″ class="t tr"&amp;gt;â��&amp;lt;/div&amp;gt;

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

&lt;/div&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%2Fkqwx6hve3n4k6mida5nv.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%2Fkqwx6hve3n4k6mida5nv.png" alt="ios browser text selection" width="800" height="780"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We simply apply the correct styling and letter spacing to each element via its class and ID attributes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction of Parent Divs
&lt;/h2&gt;

&lt;p&gt;To reduce the large amount of class=”t”, which is a CSS class in our older output that contained some CSS rules common to all of our text and other repeated values in the CSS for each div’s ID, we introduced several parent divs that reduce file size and make our CSS easier to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example of Current Output
&lt;/h2&gt;

&lt;p&gt;Below you can see an example of the current output and it’s structure (Note: As with the previous example, this is just a snippet of the relevant parts of our output):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body style="background-color:#919191;"&amp;gt;
&amp;lt;div id="jpedal" style="position:relative; width: 984px; height: 1179px; overflow: hidden; margin: 0 auto; box-shadow: 0 2px 6px rgba(100, 100, 100, 0.5);"&amp;gt;
&amp;lt;!– Begin shared CSS values –&amp;gt;
&amp;lt;!–[if lt IE 9]&amp;gt;&amp;lt;style type="text/css"&amp;gt;.text div div{zoom: 25%;}&amp;lt;/style&amp;gt;&amp;lt;![endif]–&amp;gt;
&amp;lt;style type="text/css" &amp;gt;
.text {
position: absolute;
-webkit-transform-origin: top left;
-moz-transform-origin: top left;
-o-transform-origin: top left;
-ms-transform-origin: top left;
-webkit-transform: scale(0.25);
-moz-transform: scale(0.25);
-o-transform: scale(0.25);
-ms-transform: scale(0.25);
z-index: 1;
}
.text div div {
position:absolute;
white-space:nowrap;
overflow:visible;
}
&amp;lt;/style&amp;gt;
&amp;lt;!– End shared CSS values –&amp;gt;
&amp;lt;!– Begin inline CSS –&amp;gt;
&amp;lt;style type="text/css" &amp;gt;
#t1_1{left:360px;top:240px;}
#t2_1{-webkit-transform:matrix(0.97,0,-0.2,0.97,456, 724);-ms-transform:matrix(0.97,0,-0.2,0.97,456, 724);-moz-transform:matrix(0.97,0,-0.2,0.97,456, 724);-o-transform:matrix(0.97,0,-0.2,0.97,456, 724);}
#t3_1{-webkit-transform:matrix(0.97,0,-0.2,0.97,1400, 848);-ms-transform:matrix(0.97,0,-0.2,0.97,1400, 848);-moz-transform:matrix(0.97,0,-0.2,0.97,1400, 848);-o-transform:matrix(0.97,0,-0.2,0.97,1400, 848);}
#t4_1{left:1456px;top:848px;}
#t2_1,#t3_1 {
-webkit-transform-origin: left top;
-ms-transform-origin: left top;
-moz-transform-origin: left top;
-o-transform-origin: left top;
}
.s2_1{
FONT-SIZE: 84px;
FONT-FAMILY: IGNACK-RaleighBT-Roman1;
color: rgb(35,32,32);
}
.s1_1{
FONT-SIZE: 240px;
FONT-FAMILY: CataneoBT-Regular1;
color: rgb(0,85,149);
}
.s3_1{
FONT-SIZE: 52px;
FONT-FAMILY: IGNACK-RaleighBT-Roman1;
color: rgb(35,32,32);
}
&amp;lt;/style&amp;gt;
&amp;lt;!– End inline CSS –&amp;gt;
&amp;lt;!– Begin embedded font definitions –&amp;gt;
&amp;lt;style type="text/css" &amp;gt;
@font-face {
font-family: CataneoBT-Regular1;
src: url("index/fonts/CataneoBT-Regular.woff");
}
@font-face {
font-family: IGNACK-RaleighBT-Roman1;
src: url("index/fonts/IGNACK-RaleighBT-Roman.woff");
}
&amp;lt;/style&amp;gt;
&amp;lt;!– End embedded font definitions –&amp;gt;
&amp;lt;!– Begin text definitions (Positioned/styled in CSS) –&amp;gt;
&amp;lt;div class="text"&amp;gt;
&amp;lt;div class="s1_1″&amp;gt;
&amp;lt;div id="t1_1″&amp;gt;Some things never change&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class="s2_1″&amp;gt;
&amp;lt;div id="t2_1″&amp;gt;Never trust a dog to watch your food.&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class="s3_1″&amp;gt;
&amp;lt;div id="t3_1″&amp;gt;â��&amp;lt;/div&amp;gt;

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

&lt;/div&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%2Fluk68lnp17xwq5lsshyn.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%2Fluk68lnp17xwq5lsshyn.png" alt="ios browser screenshot" width="800" height="780"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This reduced our output length by a lot; not having to output the font-family per ID and the class=”t” per element adds up to a lot of saved characters in the output files, which consequently makes large converted files with a lot of similar text smaller.&lt;/p&gt;

&lt;p&gt;However, nesting these absolutely positioned elements appears to be what the issue is in iOS. This probably isn’t intended behaviour and may well be a bug with iOS!&lt;/p&gt;

&lt;h2&gt;
  
  
  Workaround and Conclusion
&lt;/h2&gt;

&lt;p&gt;One solution we’ve come up with for this is to change the output on the page when navigated to in iOS to something it can select the text of. Of course, this affects the performance of our output when looked at on iOS devices, which isn’t the best compromise.&lt;/p&gt;

&lt;p&gt;My personal hope is that this issue is rectified within iOS itself so that other developers don’t have to encounter this oddity.&lt;/p&gt;

&lt;p&gt;Have you had any difficulties with selecting text on iOS or other web browsers? We’d love to hear about them and how you solved them!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>html</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Convert CCITT data to TIFF image (Tutorial)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Mon, 27 Jul 2026 11:27:37 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-convert-ccitt-data-to-tiff-image-tutorial-5e98</link>
      <guid>https://dev.to/idrsolutions/how-to-convert-ccitt-data-to-tiff-image-tutorial-5e98</guid>
      <description>&lt;h2&gt;
  
  
  What is CCITT data?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.idrsolutions.com/what-is-ccitt-compression//" rel="noopener noreferrer"&gt;CCITT&lt;/a&gt; is used to compress black and white image data. Using Huffman encoding, the data is squeezed into a much smaller compressed stream.&lt;/p&gt;

&lt;p&gt;CCITT is also a compression format used in the TIFF file format. By adding some additional bytes to your raw CCITT data, and saving it in a file ending .tif, you can create a TIFF Image from raw CCITT data. My example is written in Java (but it should be easy to recode in any language). It  will take the raw data and add the required bytes.&lt;/p&gt;

&lt;h2&gt;
  
  
  CCITT data in PDF files
&lt;/h2&gt;

&lt;p&gt;CCITT is used as a compression format in PDF files for images in XObjects. You can manually extract the CCITT data and the Dictionary values (K, isBlack, etc) from PDF files if you want to reuse the images. &lt;/p&gt;

&lt;p&gt;If you have extracted the CCITT data from a PDF, there may be some differences between the raw image and the image in the PDF – remember this is the raw image which may be inverted, coloured, clipped, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to convert CCITT to a TIFF
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Get the CCITT parameters&lt;/li&gt;
&lt;li&gt;Create a metadata header&lt;/li&gt;
&lt;li&gt;Append the raw CCITT data&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  and the Java code to write TIFF…
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * default values (these may be set in a PDF DecodeParms dictionary)
 */&lt;/span&gt; 
&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;isBlack&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="c1"&gt;//flag to show if default is black/white&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;k&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;w&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;h&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="cm"&gt;/*
 * build the image
 */&lt;/span&gt; 
&lt;span class="nc"&gt;ByteArrayOutputStream&lt;/span&gt; &lt;span class="n"&gt;bos&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;ByteArrayOutputStream&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="cm"&gt;/*
 * tiff header (id, version, offset)
 */&lt;/span&gt; 
&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;headerValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"4d"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4d"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2a"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"08"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;headerValues&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="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt;
    &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;headerValues&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;tagCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// appears to be minimum needed&lt;/span&gt;
&lt;span class="c1"&gt;// writeWord and writeTag are convenience methods&lt;/span&gt;
&lt;span class="c1"&gt;// add the values as bytes to the stream&lt;/span&gt;

&lt;span class="cm"&gt;/* IFD – Image File Directory */&lt;/span&gt; 
&lt;span class="n"&gt;writeWord&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tagCount&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// num of entries&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"256"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// width&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"257"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// length&lt;/span&gt;

&lt;span class="c1"&gt;// BitsPerSample 258 – B&amp;amp;W 1 bit image&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"258"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00010000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&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;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"259"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00030000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// compression&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;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;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"259"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00020000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// compression&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"259"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00040000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// compression&lt;/span&gt;

&lt;span class="c1"&gt;//photometricInterpretation&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isBlack&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"262"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00000000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
   &lt;span class="nf"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"262"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00010000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//stripOffsets -start of data after tables&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"273"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"122"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//samplesPerPixel&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"277"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"03"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"00010000h"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//rowsPerStrip – uses height&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"278"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//stripByteCount – 1 strip so all data&lt;/span&gt;
&lt;span class="n"&gt;writeTag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"279"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"04"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&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="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// write next IOD offset  zero as no other table&lt;/span&gt;
&lt;span class="n"&gt;writeDWord&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/*
 * write the CCITT image data at the end
 */&lt;/span&gt; 
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&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="nc"&gt;LogWriter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[PDF] Tiff exception  "&lt;/span&gt; &lt;span class="o"&gt;+&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="cm"&gt;/* save data as image */&lt;/span&gt; 
&lt;span class="k"&gt;try&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;fos&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;fileName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;fos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toByteArray&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;fos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&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;Error&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;LogWriter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[PDF] Tiff error "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;err&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;Exception&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;LogWriter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[PDF] Tiff exception  "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="o"&gt;);&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;p&gt;In this tutorial you learned how to change CCITT data to a TIFF image, we have many more blog posts for Java developers working with image technology. Please feel free to check them out.&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>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to extract clipped images from PDF file in Java</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 22 Jul 2026 14:51:10 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-extract-clipped-images-from-pdf-file-in-java-30ph</link>
      <guid>https://dev.to/idrsolutions/how-to-extract-clipped-images-from-pdf-file-in-java-30ph</guid>
      <description>&lt;p&gt;This tutorial shows you how to extract clipped images from a PDF file in 5 simple steps using the &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal&lt;/a&gt; PDF library. JPedal is the best Java PDF library for developers. Clipped images are raw images that have had their formats edited; this includes cropping, flipping, resizing and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Extract clipped images from PDF files?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;1. Add JPedal to your class or module path. (download the trial jar).&lt;/li&gt;
&lt;li&gt;Create a File handle, InputStream, or URL pointing to the PDF file&lt;/li&gt;
&lt;li&gt;Include a password if file is password-protected&lt;/li&gt;
&lt;li&gt;Open the PDF file&lt;/li&gt;
&lt;li&gt;Iterate over the images on each page&lt;/li&gt;
&lt;li&gt;Close the PDF file&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  and the Java code to extract clipped images…
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&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;"/path/to/document.pdf"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;ExtractClippedImages&lt;/span&gt; &lt;span class="n"&gt;extract&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;ExtractClippedImages&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="c1"&gt;//extract.setPassword("password");&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openPDFFile&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="n"&gt;pageCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract&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;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;page&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;page&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;page&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="n"&gt;imagesOnPageCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getImageCount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;image&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;image&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;imagesOnPageCount&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="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClippedImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&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="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;closePDFfile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why use a third-party library to handle PDF files?
&lt;/h2&gt;

&lt;p&gt;PDF files are a very complex binary/text hybrid data structure. The image data, color information, clipping and scaling details are all stored separately in a compressed format and need to be extracted and combined together.&lt;/p&gt;

&lt;p&gt;A third-party library handles all of this for you automatically. In this example, we will use our &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal&lt;/a&gt; PDF library. This provides an easy-to-use Java PDF APi so you can work with PDF files easily in Java.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extract clipped images from a PDF file with JPedal
&lt;/h2&gt;

&lt;p&gt;If you are looking to use JPedal to extract clipped images from PDF files, we recommend you start with these tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/extract-images/extract-images-from-pdf" rel="noopener noreferrer"&gt;How to extract images programmatically in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/extract-images/extract-clipped-images-from-pdf" rel="noopener noreferrer"&gt;How to extract clipped images programmatically in Java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>pdf</category>
    </item>
    <item>
      <title>Why convert PDF magazines to HTML5?</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Mon, 20 Jul 2026 09:40:11 +0000</pubDate>
      <link>https://dev.to/idrsolutions/why-convert-pdf-magazines-to-html5-27am</link>
      <guid>https://dev.to/idrsolutions/why-convert-pdf-magazines-to-html5-27am</guid>
      <description>&lt;p&gt;In these articles, we talk about the advantages of converting your PDF documents to HTML5. Each point has a full supporting article with a more in-depth discussion on that point. Don’t forget to check back in the future, as we are continually adding to this list!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.idrsolutions.com/why-convert-pdf-magazines-to-html5-part-1-gain-control-of-your-content/" rel="noopener noreferrer"&gt;Gain control of your content&lt;/a&gt; – Many companies offer services where they will offer a viewer for your content on the basis that they host it for you. Not us; we let you take the credit for your content, along with the SEO that naturally comes with it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SEO and the long tail – It is likely that you have a lot of back issues containing lots of well-written content full of all the right keywords. We let you convert this into a format that all search engines can understand, and allow you to take the credit for it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The best ‘browser’ for your PDF content – Many services convert into a proprietary format (such as Flash) where you lose a lot of features (e.g. text selection). You can benefit by converting to a tried and tested format with billions of users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it easy for foreign readers – Many services convert into a format with ‘fake’ (unchangable) text. We convert to real text that can be altered, for example by many web browsers that offer built-in web page translation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publish Everywhere – People are browsing content on an ever-increasing range of devices. Converting to HTML5 will give your content a consistent interface across a wide range of HTML5-capable devices. Read more…&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load quickly and save on bandwidth – One of the issues with PDF is that regardless of how much of the PDF you view, it is required to download the complete file. By converting to HTML5, your magazine readers only have to download the pages they actually read, and you can even create bespoke versions at different quality or zoom levels to optimise for mobile devices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.idrsolutions.com/why-convert-pdf-magazines-to-html5-part-7-measure-content-with-analytics/" rel="noopener noreferrer"&gt;Measure content performance with analytics&lt;/a&gt; – Analytics is vitally important to give you performance data about your content, as well as the opportunity to learn about the demographics of your content readers. By converting to HTML5, you can enable analytics and start improving your content’s performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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>java</category>
      <category>pdf</category>
      <category>html</category>
      <category>programming</category>
    </item>
    <item>
      <title>How Does CCITT Compress Image Data?</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Thu, 16 Jul 2026 11:23:26 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-does-ccitt-compress-image-data-7fm</link>
      <guid>https://dev.to/idrsolutions/how-does-ccitt-compress-image-data-7fm</guid>
      <description>&lt;h2&gt;
  
  
  How does CCITT compression work?
&lt;/h2&gt;

&lt;p&gt;CCITT encodes black-and-white data. It does this by encoding runs of black or white pixels. We can do this in various ways &lt;u&gt;(G31D/ G32D/G42D)&lt;/u&gt;. They are also known as Group 3/ Group 4 compression. We explain how the most common type (G31D) works in detail below.&lt;/p&gt;

&lt;p&gt;As most images contain more white than black, we assume that we start with white. For cases where we do not start with white, we add a marker at the start to show this.&lt;/p&gt;

&lt;p&gt;If we encode black as value 1, we just set these bits in our decompressed data – we do not explicitly need to set white values (because it is binary, not setting a value to black means that it is white).&lt;/p&gt;

&lt;p&gt;But sometimes, we find that there are more pixels that are black than white. Well, in this case, we can just invert the image (flipping bits is very fast) and then we get the best compression.&lt;/p&gt;

&lt;p&gt;All we need is a flag (&lt;strong&gt;BlackIs1&lt;/strong&gt; in the PDF file format – its default value is false) to flag that the image data needs inversion to appear correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does G31D compression work?
&lt;/h2&gt;

&lt;p&gt;This is the simpler form of CCITT to decode. Firstly, here are some keywords that would make it easier to understand how G31D works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Terms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pixel run- Usually 1-bit, 1 for Black and 0 for White. A block of pixels all the same.&lt;/li&gt;
&lt;li&gt;Scan line– The width of data from one end of the page to the other.&lt;/li&gt;
&lt;li&gt;Code Words– This contains information regarding what the data does, e.g., makeup or terminating.&lt;/li&gt;
&lt;li&gt;Run Length– Block of either White or Black bits to be decoded/ encoded.&lt;/li&gt;
&lt;li&gt;End of line(EOL)- Unique 12-bit code word used to determine the start and end of a scan line.&lt;/li&gt;
&lt;/ul&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%2F6yy0k9fuxp3x0sp0qtyl.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%2F6yy0k9fuxp3x0sp0qtyl.png" alt="EOL Code" width="167" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return to control(RTC)- Six EOL code words occurring consecutively usually determine the end of the file. EOL &amp;amp; RTC would become more obvious in later blogs.&lt;/li&gt;
&lt;/ul&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%2Fhlv2fjv10bx4q00i2dhz.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%2Fhlv2fjv10bx4q00i2dhz.png" alt="RTC" width="513" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of G31D
&lt;/h2&gt;

&lt;p&gt;G31D CCITT is a variation of the &lt;strong&gt;Huffman keyed compression&lt;/strong&gt; scheme. Essentially, to decode a G31D PDF file, a scan line is read in single-bit pixel runs. Each of these bits represents a number of white or black pixels.&lt;/p&gt;

&lt;p&gt;The black and white run lengths alternate and vary in length making them uniquely identified when decoded, the maximum size of the run lengths is bounded by the maximum width of the scan line (page width).&lt;/p&gt;

&lt;p&gt;More frequently occurring run-lengths are assigned to smaller code words while less frequently occurring run-lengths are assigned to longer code words. This is particularly useful as in a typical handwritten or printed document more short run-lengths are encountered than long run-lengths.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encoding and Decoding Process
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;While still on the subject of pixel runs and run-lengths, it is important to mention facts about how pixel runs are encoded which in turn makes it easier to decode.&lt;/li&gt;
&lt;li&gt;Pixel runs which are between 0 and 63 pixels in length are generally encoded using a single terminating code while runs between 64 and 2623 are encoded by a single make up code and a terminating code.&lt;/li&gt;
&lt;li&gt;When the run length is above 2623 pixels, they are encoded using as many make up codes as needed and only a terminating code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Firstly, a pre-calculated lookup table for both the black and white pixel runs has to be created against which the current data is compared. You want to be able to keep track of your current bit location in the scan line.&lt;/p&gt;

&lt;p&gt;This is so that when a different bit is hit, be it black or white, the decoder can group the previous bits into a code word of either make-up (longer code words) or terminating (shorter code words) code words, which are then checked against the table and decoded as needed.&lt;/p&gt;

&lt;p&gt;The make-up code word represents long run-lengths, while the short run-length is represented by the terminating cord-words. The sum of the length values of each code word makes up the run length. The process is repeated as new EOLs are hit.&lt;/p&gt;

&lt;p&gt;It is also worth mentioning that each EOL usually starts with a white run-length code word. But there are some unusual cases where it does not follow the norm i.e. begins with a black run-length.&lt;/p&gt;

&lt;p&gt;In this situation, the beginning of that scan is preceded by a zero-length white run-length code word. However, if 6 EOLs are hit consecutively, then this denotes the end of the file, i.e. RTC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages and Disadvantages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good compression of black and white data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot optimise across lines or for multiple empty lines.&lt;/li&gt;
&lt;li&gt;Takes a while to get to grips with the algorithm.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Do you need to read or write TIFF files in Java?
&lt;/h2&gt;

&lt;p&gt;Our JDeli image library (the best enterprise-level Java image library for performance and efficiency) offers &lt;a href="https://www.idrsolutions.com/jdeli/imageio-plugin" rel="noopener noreferrer"&gt;a range of advantages&lt;/a&gt; over ImageIO and alternatives for TIFF files, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prevents heap-related JVM crashes&lt;/li&gt;
&lt;li&gt;reads 1-32 bit bilevel, grayscale, RGB, argb, cmyk, acmyk, ycbcr Colorspaces, and converts to sRGB BufferedImage&lt;/li&gt;
&lt;li&gt;implements both Little and Big Endian Byte Ordering&lt;/li&gt;
&lt;li&gt;decompresses uncompressed, CCITT group 3 and 4, Deflate/Adobe Deflate, LZW, Packbits&lt;/li&gt;
&lt;li&gt;support for Single, Multi-file, Tiling, Planar (Chunky, Separated), Predictor, 16,32 bit floating samples&lt;/li&gt;
&lt;li&gt;improve read performance&lt;/li&gt;
&lt;li&gt;supports threading&lt;/li&gt;
&lt;li&gt;superior image scaling algorithms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.idrsolutions.com/jdeli/" rel="noopener noreferrer"&gt;Learn more&lt;/a&gt; about JDeli, and try it yourself.&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>
    </item>
    <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>
  </channel>
</rss>
