<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: IDRSolutions</title>
    <description>The latest articles on DEV Community by IDRSolutions (@idrsolutions).</description>
    <link>https://dev.to/idrsolutions</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3078638%2Faa7ba4ef-f446-48e3-95e9-0c43d0c3e214.png</url>
      <title>DEV Community: IDRSolutions</title>
      <link>https://dev.to/idrsolutions</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/idrsolutions"/>
    <language>en</language>
    <item>
      <title>How to debug PDF files</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 21 Aug 2026 13:09:55 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-debug-pdf-files-n5k</link>
      <guid>https://dev.to/idrsolutions/how-to-debug-pdf-files-n5k</guid>
      <description>&lt;p&gt;The first JPedal release of 2023 has just been published and with it, some exciting new features have been added to our Java PDF debugger! With a PDF debugger, you can inspect and debug PDF files easily. Read about our new release &lt;a href="https://www.idrsolutions.com/docs/jpedal/release-notes/2023/2023-01-release-notes" rel="noopener noreferrer"&gt;here&lt;/a&gt; to find out more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Images in the PDF debugger
&lt;/h2&gt;

&lt;p&gt;You can now view images in JPedal’s own PDF debugger.&lt;/p&gt;

&lt;p&gt;The Xref Viewer and the Object Tree Viewer both allow you to view the image content of XObjects. This can be done by selecting an XObject and pressing ‘Show Image’.&lt;/p&gt;

&lt;p&gt;The Command Window allows you to view the image content of ID and DO commands. This can be done by right-clicking on the command and pressing ‘View Image’.&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%2F8m0yit4ttulgvxuw9wjd.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%2F8m0yit4ttulgvxuw9wjd.png" alt="JPedal PDF Inspector" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more about viewing images in the inspector &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/viewer/inspect-the-contents-of-pdf-files-with-the-inspector#view-images" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debug Breakpoints
&lt;/h2&gt;

&lt;p&gt;The Limit Decode Slider in the PDF debugger now has breakpoints.&lt;/p&gt;

&lt;p&gt;You can select a command to toggle a breakpoint and pressing the resume button will decode the page up until the next breakpoint.&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%2Fnhn8qvgfhqbobvmfku4r.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%2Fnhn8qvgfhqbobvmfku4r.png" alt="Breakpoints JPedal PDF Inspector" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more about breakpoints &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/viewer/inspect-the-contents-of-pdf-files-with-the-inspector#pause-decoding-at-a-specific-command" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Xref Viewer Improvements
&lt;/h2&gt;

&lt;p&gt;The Xref Viewer has been updated and now supports cross-reference streams as well as Xref tables.&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%2Ff76kdkbls9y8fbkdk79m.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%2Ff76kdkbls9y8fbkdk79m.png" alt="Xref Viewer JPedal PDF Inspector" width="750" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more about the Xref Viewer &lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/viewer/inspect-the-contents-of-pdf-files-with-the-inspector#view-the-cross-references" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;You can read more about JPedal’s PDF inspector &lt;a href="https://www.idrsolutions.com/jpedal/pdf-inspector" rel="noopener noreferrer"&gt;on our website&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>PDF Performance and UX Issues in Web Publishing (Why PDFs Slow Down Websites)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 19 Aug 2026 08:50:56 +0000</pubDate>
      <link>https://dev.to/idrsolutions/pdf-performance-and-ux-issues-in-web-publishing-why-pdfs-slow-down-websites-53h2</link>
      <guid>https://dev.to/idrsolutions/pdf-performance-and-ux-issues-in-web-publishing-why-pdfs-slow-down-websites-53h2</guid>
      <description>&lt;h2&gt;
  
  
  Why PDFs Cause Performance and UX Issues in Web Publishing
&lt;/h2&gt;

&lt;p&gt;Embedding PDFs in websites is a common approach for digital publishing platforms, but it often introduces performance and user experience issues that are difficult to control.&lt;/p&gt;

&lt;p&gt;If you manage a publishing platform, content hub, or document-heavy application, you have likely seen slow load times, poor mobile usability, and limited flexibility when working with PDFs in the browser.&lt;/p&gt;

&lt;p&gt;Understanding why PDFs struggle in web environments is key to improving both content performance and user engagement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do PDFs Load Slowly on Websites?
&lt;/h2&gt;

&lt;p&gt;PDFs load slowly on websites because they are large, fixed layout files that require full document rendering in the browser. Unlike HTML, which loads progressively, PDFs often need to be processed in full before users can interact with them. This increases load times, especially for image-heavy or long documents, and impacts performance across devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PDFs Slow Down Websites (PDF Performance Issues)
&lt;/h2&gt;

&lt;p&gt;PDFs are typically large, high-fidelity files designed to preserve layout and visual accuracy. While this is useful for print and distribution, it creates performance challenges when delivered through a browser.&lt;/p&gt;

&lt;p&gt;Rendering a PDF requires significant browser resources. Instead of loading lightweight, structured web content, the browser must process an entire document, often including high-resolution images and complex formatting.&lt;/p&gt;

&lt;p&gt;For publishing platforms, this results in slower page load times, delayed interaction, and inconsistent rendering across devices. As content libraries scale, these performance issues compound, impacting overall site speed and increasing bounce rates.&lt;/p&gt;

&lt;p&gt;The impact is even more pronounced on mobile, where bandwidth and processing power are limited, and users expect fast, responsive experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  PDF User Experience Problems (Mobile and Responsive Issues)
&lt;/h2&gt;

&lt;p&gt;PDFs are not designed to be responsive. On mobile devices, users often need to zoom, pan, and manually navigate documents just to read basic content.&lt;/p&gt;

&lt;p&gt;This creates friction compared to native web pages, where content automatically adapts to screen size and supports intuitive scrolling and interaction.&lt;/p&gt;

&lt;p&gt;For publishers, this directly affects engagement metrics. When users struggle to consume content, they are more likely to drop off, reducing time on page and overall retention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PDFs Don’t Work Well on Websites
&lt;/h2&gt;

&lt;p&gt;At a fundamental level, PDFs were built for print, not for the web. They are fixed-layout documents, whereas modern web experiences rely on flexible, responsive, and interactive content.&lt;/p&gt;

&lt;p&gt;When PDFs are embedded into websites, they rely on browser-based rendering engines that limit performance, control, and consistency. This makes it difficult for publishing teams to optimise content delivery, personalise experiences, or integrate seamlessly with web analytics and workflows.&lt;/p&gt;

&lt;p&gt;As a result, PDFs often become a constraint rather than an enabler in digital publishing environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better Alternatives to PDFs for Web Publishing
&lt;/h2&gt;

&lt;p&gt;To address these challenges, many publishing platforms are moving towards web-native formats such as HTML5 and SVG.&lt;/p&gt;

&lt;p&gt;By converting PDFs into HTML5 content, publishers can deliver faster load times, responsive layouts, and a more seamless reading experience across devices.&lt;/p&gt;

&lt;p&gt;This approach also provides greater control over content structure, styling, and interaction, making it easier to optimise performance, improve accessibility, and integrate with existing web systems.&lt;/p&gt;

&lt;p&gt;For publishing teams managing large volumes of content, this shift enables better scalability and a more consistent user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Fix PDF Performance and UX Issues in Web Publishing
&lt;/h2&gt;

&lt;p&gt;PDFs remain useful for document distribution, but they introduce clear limitations when used within web publishing platforms.&lt;/p&gt;

&lt;p&gt;If performance, responsiveness, and user engagement are priorities, relying on embedded PDFs can hold your platform back.&lt;/p&gt;

&lt;p&gt;Converting PDFs into web-native formats offers a more scalable and user-friendly solution. Tools like BuildVu enable publishing teams to transform PDFs into fast, responsive HTML5 content that works seamlessly in the browser.&lt;/p&gt;

&lt;p&gt;By making this shift, publishing platforms can reduce friction, improve load times, and create a better experience for their users.&lt;/p&gt;

&lt;p&gt;Explore more ways to improve digital publishing performance, user experience, and content delivery at scale. &lt;a href="https://www.idrsolutions.com/buildvu/?mtm_campaign=PublishingICP" rel="noopener noreferrer"&gt;Trial BuildVu now&lt;/a&gt; to convert your PDFs into fast, web-native HTML5 content.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>html</category>
      <category>pdf</category>
    </item>
    <item>
      <title>Comparing TIFF Compression Algorithms</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:47:38 +0000</pubDate>
      <link>https://dev.to/idrsolutions/comparing-tiff-compression-algorithms-32an</link>
      <guid>https://dev.to/idrsolutions/comparing-tiff-compression-algorithms-32an</guid>
      <description>&lt;p&gt;In this post, we will be exploring the different TIFF compression techniques you can use. We will investigate their effect on different metrics such as file size, quality of output, and speed. We will be using our image library JDeli to compress a TIFF file (sample image). &lt;a href="https://www.idrsolutions.com/jdeli/" rel="noopener noreferrer"&gt;JDeli&lt;/a&gt; is the best pure Java image library for performance and efficiency.&lt;/p&gt;

&lt;p&gt;For the baseline of our comparisons, we will use the following uncompressed image. It has a file size of 39.3MB. It takes just under 5 seconds to encode.&lt;/p&gt;

&lt;h2&gt;
  
  
  JPEG
&lt;/h2&gt;

&lt;p&gt;First introduced in the 90s, JPEG has remained a popular compression format for images due to its decent tradeoff between quality and file size. JPEG is lossy meaning you cannot recover the original pixel data from the compressed image.&lt;/p&gt;

&lt;p&gt;Straight off the bat, we see a dramatic reduction in file size: 1.2MB! Even with this tiny file size, the quality of the image is only slightly worse than the original. &lt;/p&gt;

&lt;p&gt;Viewing at its default resolution, it is hard to tell the difference, however upon zooming in you will notice a less sharp image with slightly more noise and artefacts. Using JPEG compression, the encoding takes around 5 seconds, it is almost as quick as the original.&lt;/p&gt;

&lt;h2&gt;
  
  
  LZW
&lt;/h2&gt;

&lt;p&gt;Lempel–Ziv–Welch (named after its creators) was introduced in 1984, and is used today by Unix’s compress program. It is also the compression algorithm used in GIF images.&lt;/p&gt;

&lt;p&gt;Using LZW compression, we observe a file size of 18MB. Since LZW is lossless, there is no reduction in the quality of the image. Like JPEG, encoding with LZW takes around 5 seconds.&lt;/p&gt;

&lt;p&gt;An interesting quirk about LZW is that is has the potential to make file sizes bigger. An image with lots of noise will not see a reduced file size if compressed with LZW.&lt;/p&gt;

&lt;h2&gt;
  
  
  DEFLATE
&lt;/h2&gt;

&lt;p&gt;DEFLATE was also designed in the 90s and is popular in PNG images and also the ZIP archive format.&lt;/p&gt;

&lt;p&gt;Using DEFLATE, the file size is reduced. Like LZW, DEFLATE is lossless, so the quality of the compressed image remains the same as the original. The downside of DEFLATE however, is that it takes much longer to encode.&lt;/p&gt;

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

&lt;p&gt;In conclusion, there is no best tiff compression algorithm that solves all problems. JPEG is best if you want a tiny file size with a small reduction in quality however LZW and DEFLATE are necessary if you want to preserve the original image. LZW encodes slightly larger than DEFLATE but is much faster so the answer will depend on your use case.&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 find PDF page size in Java (Tutorial)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 12 Aug 2026 10:00:48 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-find-pdf-page-size-in-java-tutorial-1n93</link>
      <guid>https://dev.to/idrsolutions/how-to-find-pdf-page-size-in-java-tutorial-1n93</guid>
      <description>&lt;p&gt;PDF files are not directly supported by Java. This tutorial shows you how to extract PDF page size (height and width) from a PDF file in simple steps using the &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal Java PDF library&lt;/a&gt;. JPedal is the best Java PDF library for developers. The page size can be defined in Centimetres, Inches and pixels.&lt;/p&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 which is a subset of the even more complicated Postscript format. In this example, we will use our &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal&lt;/a&gt; Java PDF library to make this task simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to find PDF page size in Java
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add JPedal to your class or module path. (download the &lt;a href="https://www.idrsolutions.com/jpedal/#why-buy" rel="noopener noreferrer"&gt;trial jar&lt;/a&gt;).&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 password protected&lt;/li&gt;
&lt;li&gt;Open the PDF file&lt;/li&gt;
&lt;li&gt;Extract the data for 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 find PDF Page size…
&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;PdfUtilities&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;PdfUtilities&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//if needed&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="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;float&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pageDimensions&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;getPageDimensions&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pageNum&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;PageUnits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Inches&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;PageSizeType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CropBox&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;
  
  
  Further useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Blog post explaining how &lt;a href="https://blog.idrsolutions.com/what-is-pdf-pagesize/" rel="noopener noreferrer"&gt;MediaBox and CropBox define a PDF page size&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Javadoc link to &lt;a href="https://files.idrsolutions.com/maven/site/jpedal/apidocs/org/jpedal/examples/PdfUtilities.PageSizeType.html" rel="noopener noreferrer"&gt;PageSizeType class&lt;/a&gt; which defines whether to use MediaBox or CropBox (if in doubt use CropBox)&lt;/li&gt;
&lt;li&gt;Javadoc link to &lt;a href="https://files.idrsolutions.com/maven/site/jpedal/apidocs/org/jpedal/examples/PdfUtilities.PageUnits.html" rel="noopener noreferrer"&gt;PageUnits class&lt;/a&gt; which defines sizes&lt;/li&gt;
&lt;li&gt;Javadoc link to &lt;a href="https://files.idrsolutions.com/maven/site/jpedal/apidocs/org/jpedal/examples/PdfUtilities.html" rel="noopener noreferrer"&gt;PageUtilities class&lt;/a&gt; which documents this Utility class&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>pdf</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Measure content performance with Analytics – Why convert PDF magazines to HTML5?</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Fri, 07 Aug 2026 13:22:43 +0000</pubDate>
      <link>https://dev.to/idrsolutions/measure-content-performance-with-analytics-why-convert-pdf-magazines-to-html5-h4d</link>
      <guid>https://dev.to/idrsolutions/measure-content-performance-with-analytics-why-convert-pdf-magazines-to-html5-h4d</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%2Fh8khvat06o2s8z3a2bl9.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%2Fh8khvat06o2s8z3a2bl9.png" alt="Analytics Dashboard" width="799" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the things that all good content producers rely heavily on is analytics. Analytics give you the opportunity to see what is doing well (the stuff you need to do more of), and what isn’t doing well (the stuff you need to do less of).&lt;/p&gt;

&lt;p&gt;Not only do they let you know about the performance of your content, but they can also give you information about the people consuming your content. For example, there is a 7.28% chance that you are reading this from Germany (shout out to our German readers!). This allows you to tailor your content to your demographics and to bring in better quality traffic.&lt;/p&gt;

&lt;p&gt;For those of you advertising to your readers, you can also increase your ad revenue by targeting your readers with adverts that you know are most relevant to them. For example there are companies that pay Facebook good money to display their dating website advert to the users who have recently set their relationship status to Single.&lt;/p&gt;

&lt;p&gt;Unfortunately this is something that PDF is completely lacking, but by converting to HTML5 you can enable this functionality, and start measuring your content and demographics!&lt;/p&gt;

&lt;p&gt;You can use our &lt;a href="https://www.idrsolutions.com/online-pdf-to-html5-converter/" rel="noopener noreferrer"&gt;online converter&lt;/a&gt; to test the PDF conversion to HTML. Try out some sample copies and start tracking right away!&lt;/p&gt;

&lt;p&gt;This article is part of a series where we talk about the advantages of publishing your PDF magazines online as HTML5. &lt;a href="https://blog.idrsolutions.com/why-convert-pdf-magazines-to-html5-series-index/" rel="noopener noreferrer"&gt;Click here&lt;/a&gt; to see more advantages.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>html</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Java CMYK to RGB Conversion – Speed Comparison</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Thu, 06 Aug 2026 14:03:12 +0000</pubDate>
      <link>https://dev.to/idrsolutions/java-cmyk-to-rgb-conversion-speed-comparison-1onl</link>
      <guid>https://dev.to/idrsolutions/java-cmyk-to-rgb-conversion-speed-comparison-1onl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Some optimisations are best left to Java. For example a &lt;code&gt;System.arraycopy&lt;/code&gt; is the fastest way to create a new version because it is optimised in hardware inside Java. So in general, any function which might have hardware optimisation is best left to the JVM.&lt;/p&gt;

&lt;p&gt;So what about image data conversion? Is it better to delegate it to Java or Do It Yourself? I have been looking at a file which was slow to decode. The bottleneck turned out to be the CMYK to RGB conversion so I decided to have a look…&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 1: Using ColorConvertOp
&lt;/h2&gt;

&lt;p&gt;My original code used a ColorConvertOp to do the image conversion on the raw CMYK data and then create an RGB image with the converted data. Here is the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bands&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;1&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="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="cm"&gt;/**turn it into a BufferedImage so we can filter*/&lt;/span&gt;&lt;span class="nc"&gt;DataBuffer&lt;/span&gt; &lt;span class="n"&gt;db&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;DataBufferByte&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;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="cm"&gt;/**create RGB colorspace and model*/&lt;/span&gt;&lt;span class="nc"&gt;ColorSpace&lt;/span&gt; &lt;span class="n"&gt;rgbCS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;GenericColorSpace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getColorSpaceInstance&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="cm"&gt;/**define the conversion. hints can be replaced with null*/&lt;/span&gt;&lt;span class="nc"&gt;ColorConvertOp&lt;/span&gt; &lt;span class="nc"&gt;CSToRGB&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;ColorConvertOp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="nc"&gt;DeviceCMYKColorSpace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getColorSpaceInstance&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rgbCS&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
   &lt;span class="nc"&gt;ColorSpaces&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hints&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/**create RGB colorspace and model*/&lt;/span&gt;&lt;span class="nc"&gt;ComponentColorModel&lt;/span&gt; &lt;span class="n"&gt;rgbModel&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;ComponentColorModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="n"&gt;rgbCS&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;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&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="nc"&gt;ColorModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OPAQUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
   &lt;span class="nc"&gt;DataBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_BYTE&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="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;width&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;BufferedImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_INT_RGB&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;WritableRaster&lt;/span&gt; &lt;span class="n"&gt;rgbRaster&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rgbModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
   &lt;span class="nf"&gt;createCompatibleWritableRaster&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CSToRGB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Raster&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createInterleavedRaster&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bands&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;rgbRaster&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgbRaster&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;On the sample page it takes 73 seconds on my fast Mac.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 2: Manual Pixel Conversion
&lt;/h2&gt;

&lt;p&gt;Version 2 does the pixel conversion manually and then builds the image from that. A major advantage of this is that I can add optimisations. In this case I cache the last value so I only need to do the conversion if the value changes – on an empty page of 10,000 white pixels, I will get a massive boost as I only need to convert the value once and reuse it.&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;ColorSpace&lt;/span&gt; &lt;span class="no"&gt;CMYK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;DeviceCMYKColorSpace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getColorSpaceInstance&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;BufferedImage&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;new_data&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;byte&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;h&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pixelCount&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;h&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;lastC&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;lastM&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;lastY&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;lastK&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;float&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;K&lt;/span&gt;&lt;span class="o"&gt;;&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;rgb&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="cm"&gt;/**
* loop through each pixel changing CMYK values to RGB
*/&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pixelReached&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="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;pixelCount&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;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="no"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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;amp;&lt;/span&gt;&lt;span class="mh"&gt;0xff&lt;/span&gt;&lt;span class="o"&gt;)/&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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;1&lt;/span&gt;&lt;span class="o"&gt;]&amp;amp;&lt;/span&gt;&lt;span class="mh"&gt;0xff&lt;/span&gt;&lt;span class="o"&gt;)/&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="no"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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;2&lt;/span&gt;&lt;span class="o"&gt;]&amp;amp;&lt;/span&gt;&lt;span class="mh"&gt;0xff&lt;/span&gt;&lt;span class="o"&gt;)/&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="no"&gt;K&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&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;3&lt;/span&gt;&lt;span class="o"&gt;]&amp;amp;&lt;/span&gt;&lt;span class="mh"&gt;0xff&lt;/span&gt;&lt;span class="o"&gt;)/&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="n"&gt;f&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;lastC&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="no"&gt;C&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;lastM&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;lastY&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="no"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;lastK&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="no"&gt;K&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="c1"&gt;//use existing values if not changed&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;//work out new&lt;/span&gt;
&lt;span class="n"&gt;rgb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;CMYK&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toRGB&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="no"&gt;C&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="no"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="no"&gt;K&lt;/span&gt;&lt;span class="o"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;//cache values&lt;/span&gt;
&lt;span class="n"&gt;lastC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;lastM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;lastY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;lastK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;K&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pixelReached&lt;/span&gt;&lt;span class="o"&gt;++]=(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;rgb&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;255&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pixelReached&lt;/span&gt;&lt;span class="o"&gt;++]=(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;rgb&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;255&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pixelReached&lt;/span&gt;&lt;span class="o"&gt;++]=(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgb&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="mi"&gt;255&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;/**
* turn data into RGB image
*/&lt;/span&gt;&lt;span class="n"&gt;image&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;w&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="nc"&gt;BufferedImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE_INT_RGB&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Raster&lt;/span&gt; &lt;span class="n"&gt;raster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createInterleavedRaster&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_data&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;h&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raster&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Comparison
&lt;/h2&gt;

&lt;p&gt;The method is longer, but what is the speed difference? On my Mac this takes an astonishing 11 seconds! My next task is to see whether it is the same on other platforms…&lt;/p&gt;

&lt;p&gt;I’ve kept the old code (in the hope Oracle one day optimises the filter function), but for the moment you can guess which version I am using…&lt;/p&gt;

&lt;p&gt;Have you found any similar cases where a DIY approach is much faster?&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>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to search a PDF file in Java (Tutorial)</title>
      <dc:creator>IDRSolutions</dc:creator>
      <pubDate>Wed, 05 Aug 2026 13:38:29 +0000</pubDate>
      <link>https://dev.to/idrsolutions/how-to-search-a-pdf-file-in-java-tutorial-5h3f</link>
      <guid>https://dev.to/idrsolutions/how-to-search-a-pdf-file-in-java-tutorial-5h3f</guid>
      <description>&lt;p&gt;This tutorial shows you how to find words in a PDF file in simple steps using the &lt;a href="https://www.idrsolutions.com/jpedal/" rel="noopener noreferrer"&gt;JPedal&lt;/a&gt; Java PDF library. JPedal is the best Java PDF library for developers. It includes a PDF search engine that provides an easy-to-use Java PDF API to find words and phrases in a PDF document.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to search PDF file in Java
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.idrsolutions.com/jpedal/#why-buy" rel="noopener noreferrer"&gt;Download&lt;/a&gt; JPedal 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 password protected&lt;/li&gt;
&lt;li&gt;Open the PDF file&lt;/li&gt;
&lt;li&gt;Scan the pages&lt;/li&gt;
&lt;li&gt;Close the PDF file&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  and the Java code to search a PDF…
&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;FindTextInRectangle&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;FindTextInRectangle&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;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;float&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;coords&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;findTextOnPage&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="s"&gt;"textToFind"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;SearchType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MUTLI_LINE_RESULTS&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 can’t I just search the PDF file directly?
&lt;/h2&gt;

&lt;p&gt;You cannot simply search inside a PDF file because the text data is stored in a special binary format.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related tutorials
&lt;/h2&gt;

&lt;p&gt;If you are looking to search PDF files in JPedal, we recommend you start with this tutorials:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.idrsolutions.com/docs/jpedal/tutorials/search/find-text-in-a-pdf-file" rel="noopener noreferrer"&gt;How to Find Text in a PDF File using Java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>pdf</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <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>
  </channel>
</rss>
