Wednesday, 3 October 2012

Java Swing PDF Viewer

I'll use pdf-renderer to create an pdf viewer in java swing application.
  • Dependencies
  • 
        org.swinglabs
        pdf-renderer
        1.0.5
    
    
        com.google.guava
        guava
        13.0.1
    
    
  • PDF Viewer
  • import com.google.common.base.CharMatcher;
    import com.sun.pdfview.PDFFile;
    import com.sun.pdfview.PDFPage;
    import com.sun.pdfview.PagePanel;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    
    import static com.google.common.base.Strings.isNullOrEmpty;
    
    public class PdfViewer extends JPanel {
        private static enum Navigation {GO_FIRST_PAGE, FORWARD, BACKWARD, GO_LAST_PAGE, GO_N_PAGE}
    
        private static final CharMatcher POSITIVE_DIGITAL = CharMatcher.anyOf("0123456789");
        private static final String GO_PAGE_TEMPLATE = "%s of %s";
        private static final int FIRST_PAGE = 1;
        private int currentPage = FIRST_PAGE;
        private JButton btnFirstPage;
        private JButton btnPreviousPage;
        private JTextField txtGoPage;
        private JButton btnNextPage;
        private JButton btnLastPage;
        private PagePanel pagePanel;
        private PDFFile pdfFile;
    
        public PdfViewer() {
            initial();
        }
    
        private void initial() {
            setLayout(new BorderLayout(0, 0));
            JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
            add(topPanel, BorderLayout.NORTH);
            btnFirstPage = createButton("|<<");
            topPanel.add(btnFirstPage);
            btnPreviousPage = createButton("<<");
            topPanel.add(btnPreviousPage);
            txtGoPage = new JTextField(10);
            txtGoPage.setHorizontalAlignment(JTextField.CENTER);
            topPanel.add(txtGoPage);
            btnNextPage = createButton(">>");
            topPanel.add(btnNextPage);
            btnLastPage = createButton(">>|");
            topPanel.add(btnLastPage);
            JScrollPane scrollPane = new JScrollPane();
            add(scrollPane, BorderLayout.CENTER);
            JPanel viewPanel = new JPanel(new BorderLayout(0, 0));
            scrollPane.setViewportView(viewPanel);
    
            pagePanel = new PagePanel();
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            pagePanel.setPreferredSize(screenSize);
            viewPanel.add(pagePanel, BorderLayout.CENTER);
    
            disableAllNavigationButton();
    
            btnFirstPage.addActionListener(new PageNavigationListener(Navigation.GO_FIRST_PAGE));
            btnPreviousPage.addActionListener(new PageNavigationListener(Navigation.BACKWARD));
            btnNextPage.addActionListener(new PageNavigationListener(Navigation.FORWARD));
            btnLastPage.addActionListener(new PageNavigationListener(Navigation.GO_LAST_PAGE));
            txtGoPage.addActionListener(new PageNavigationListener(Navigation.GO_N_PAGE));
        }
    
        private JButton createButton(String text) {
            JButton button = new JButton(text);
            button.setPreferredSize(new Dimension(55, 20));
    
            return button;
        }
    
        private void disableAllNavigationButton() {
            btnFirstPage.setEnabled(false);
            btnPreviousPage.setEnabled(false);
            btnNextPage.setEnabled(false);
            btnLastPage.setEnabled(false);
        }
    
        private boolean isMoreThanOnePage(PDFFile pdfFile) {
            return pdfFile.getNumPages() > 1;
        }
    
        private class PageNavigationListener implements ActionListener {
            private final Navigation navigation;
    
            private PageNavigationListener(Navigation navigation) {
                this.navigation = navigation;
            }
    
            public void actionPerformed(ActionEvent e) {
                if (pdfFile == null) {
                    return;
                }
    
                int numPages = pdfFile.getNumPages();
                if (numPages <= 1) {
                    disableAllNavigationButton();
                } else {
                    if (navigation == Navigation.FORWARD && hasNextPage(numPages)) {
                        goPage(currentPage, numPages);
                    }
    
                    if (navigation == Navigation.GO_LAST_PAGE) {
                        goPage(numPages, numPages);
                    }
    
                    if (navigation == Navigation.BACKWARD && hasPreviousPage()) {
                        goPage(currentPage, numPages);
                    }
    
                    if (navigation == Navigation.GO_FIRST_PAGE) {
                        goPage(FIRST_PAGE, numPages);
                    }
    
                    if (navigation == Navigation.GO_N_PAGE) {
                        String text = txtGoPage.getText();
                        boolean isValid = false;
                        if (!isNullOrEmpty(text)) {
                            boolean isNumber = POSITIVE_DIGITAL.matchesAllOf(text);
                            if (isNumber) {
                                int pageNumber = Integer.valueOf(text);
                                if (pageNumber >= 1 && pageNumber <= numPages) {
                                    goPage(Integer.valueOf(text), numPages);
                                    isValid = true;
                                }
                            }
                        }
    
                        if (!isValid) {
                            JOptionPane.showMessageDialog(PdfViewer.this, format("Invalid page number '%s' in this document", text));
                            txtGoPage.setText(format(GO_PAGE_TEMPLATE, currentPage, numPages));
                        }
                    }
                }
            }
    
            private void goPage(int pageNumber, int numPages) {
                currentPage = pageNumber;
                PDFPage page = pdfFile.getPage(currentPage);
                pagePanel.showPage(page);
                boolean notFirstPage = isNotFirstPage();
                btnFirstPage.setEnabled(notFirstPage);
                btnPreviousPage.setEnabled(notFirstPage);
                txtGoPage.setText(format(GO_PAGE_TEMPLATE, currentPage, numPages));
                boolean notLastPage = isNotLastPage(numPages);
                btnNextPage.setEnabled(notLastPage);
                btnLastPage.setEnabled(notLastPage);
            }
    
            private boolean hasNextPage(int numPages) {
                return (++currentPage) <= numPages;
            }
    
            private boolean hasPreviousPage() {
                return (--currentPage) >= FIRST_PAGE;
            }
    
            private boolean isNotLastPage(int numPages) {
                return currentPage != numPages;
            }
    
            private boolean isNotFirstPage() {
                return currentPage != FIRST_PAGE;
            }
        }
    
        public PagePanel getPagePanel() {
            return pagePanel;
        }
    
        public void setPDFFile(PDFFile pdfFile) {
            this.pdfFile = pdfFile;
            currentPage = FIRST_PAGE;
            disableAllNavigationButton();
            txtGoPage.setText(format(GO_PAGE_TEMPLATE, FIRST_PAGE, pdfFile.getNumPages()));
            boolean moreThanOnePage = isMoreThanOnePage(pdfFile);
            btnNextPage.setEnabled(moreThanOnePage);
            btnLastPage.setEnabled(moreThanOnePage);
        }
    }
    
    Line:58-59 automatically match the current screen resolution. The default is 800*600.

    The utility method "format" is here: format

  • Tester
  • public static void main(String[] args) {
            try {
                long heapSize = Runtime.getRuntime().totalMemory();
                System.out.println("Heap Size = " + heapSize);
    
                JFrame frame = new JFrame("PDF Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
                //load a pdf from a byte buffer
                File file = new File("/Users/Sean/Documents/test-pdf.pdf");
                RandomAccessFile raf = new RandomAccessFile(file, "r");
                FileChannel channel = raf.getChannel();
                ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
                final PDFFile pdffile = new PDFFile(buf);
                PdfViewer pdfViewer = new PdfViewer();
                pdfViewer.setPDFFile(pdffile);
                frame.add(pdfViewer);
                frame.pack();
                frame.setVisible(true);
    
                PDFPage page = pdffile.getPage(0);
                pdfViewer.getPagePanel().showPage(page);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
  • screen shots


Wednesday, 19 September 2012

How to create or initialize Generic Type Array


  • solution 1





  • Limitation: It's not work if input array is null.

    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
            if (array == null) {
                return null;
            }
    
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }
            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }
    
            Class<?> type = array.getClass().getComponentType();
            int newSize = endIndexExclusive - startIndexInclusive;
            if (newSize < 0) {
                final T[] emptyArray = (T[]) Array.newInstance(type, 0);
                return emptyArray;
            }
    
            T[] subarray = (T[]) Array.newInstance(type, newSize);
            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
            return subarray;
        }
    
  • solution 2
  • It's work if input array is null. But it's more verbose for invoking.
    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive, Class<T>> clazz) {
         T[] emptyArray = (T[]) Array.newInstance(clazz, 0);
    
            if (array == null) {
                return emptyArray;
            }
    
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }
            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }
    
            if (newSize < 0) {
                return emptyArray;
            }
    
            T[] subarray = (T[]) Array.newInstance(clazz, newSize);
            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
            return subarray;
        }
    

    Tuesday, 18 September 2012

    Java Swing JTextField: Number only and give length



  • Solution 1

  • Simple but It can't work for "CTRL + V" scenario
    private class NumberOnlyAdapter extends KeyAdapter {
    
            private final int maxLength;
    
            private NumberOnlyAdapter(int maxLength) {
                this.maxLength = maxLength;
            }
    
            @Override
            public void keyTyped(KeyEvent e) {
                char typed = e.getKeyChar();
                CharMatcher notDigit = noneOf("0123456789").and(isNot((char) VK_BACK_SPACE)).and(isNot((char) VK_DELETE));
                JTextField textField = (JTextField) e.getComponent();
                if (notDigit.apply(typed) || textField.getText().length() >= maxLength) {
                    e.consume();
                }
            }
    
        }
    
    ...
    int maxLength = 8;
    JTextField textField = new JTextField();
    textField.addKeyListener(new NumberOnlyAdapter(maxLength));
    
  • Solution 2

  • It's work for all conditions
    import static org.apache.commons.lang3.StringUtils.*;
    
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DocumentFilter;
    
    public class NumericOnlyAndMaxLengthFilter extends DocumentFilter {
        private int maxLength = 0;
    
    
        public NumericOnlyAndMaxLengthFilter() {
           // allow any length of numeric
        }
    
        public NumericOnlyAndMaxLengthFilter(int maxLength) {
            this.maxLength = maxLength;
        }
    
        @Override
        public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
            if (isNumeric(string)) {
                if (isExceedMaxLength(fb, string)) {
                    return;
                }
                super.insertString(fb, offset, string, attr);
            }
        }
    
        @Override
        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
            if (isNumeric(text)) {
                if (isExceedMaxLength(fb, text)) {
                    return;
                }
                super.insertString(fb, offset, text, attrs);
            }
        }
    
        private boolean isExceedMaxLength(FilterBypass fb, String text) {
            return maxLength > 0 && (fb.getDocument().getLength() + text.length()) > maxLength;
        }
    }
    
    ...
    int maxLength = 8;
    JTextField textField = new JTextField();
    ((AbstractDocument)textField .getDocument()).setDocumentFilter(new NumericOnlyAndMaxLengthFilter(maxLength));
    

    Thursday, 13 September 2012

    Maven generate HTML Junit report

    • add to pom.xml
    • 
          org.apache.maven.plugins
          maven-surefire-plugin
          
              true
          
      
      
      
          org.jvnet.maven-antrun-extended-plugin
          maven-antrun-extended-plugin
          
              
                  test-reports
                  test
                  
                      
                          
                              
                                  
                              
                              
                          
                      
                  
                  
                      run
                  
              
          
          
              
                  org.apache.ant
                  ant-junit
                  1.8.4
              
              
                  org.apache.ant
                  ant-trax
                  1.8.0
              
          
      
      
    • Don't bind the AntRun plugin to the test phase, move the configuration outside the execution and call mvn antrun:run on the command line to generate the reports when wanted.
    • Or use the testFailureIgnore option of the test mojo and set it to true in the surefire plugin
    • Use maven command arguments
    • $mvn test -Dmaven.test.failure.ignore=true
      

    Wednesday, 5 September 2012

    Java - better performance String formatter

    /**
         * Substitutes each {@code %s} in {@code template} with an argument. These
         * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
         * If there are more arguments than placeholders, the unmatched arguments will
         * be appended to the end of the formatted message in square braces.
         *
         * @param template a non-null string containing 0 or more {@code %s}
         *     placeholders.
         * @param args the arguments to be substituted into the message
         *     template. Arguments are converted to strings using
         *     {@link String#valueOf(Object)}. Arguments can be null.
         */
        public static String format(String template, Object... args) {
            template = String.valueOf(template); // null -> "null"
            // start substituting the arguments into the '%s' placeholders
            StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
            int templateStart = 0;
            int i = 0;
            while (i < args.length) {
                int placeholderStart = template.indexOf("%s", templateStart);
                if (placeholderStart == -1) {
                    break;
                }
                builder.append(template.substring(templateStart, placeholderStart));
                builder.append(args[i++]);
                templateStart = placeholderStart + 2;
            }
            builder.append(template.substring(templateStart));
    
            // if we run out of placeholders, append the extra args in square braces
            if (i < args.length) {
                builder.append(" [");
                builder.append(args[i++]);
                while (i < args.length) {
                    builder.append(", ");
                    builder.append(args[i++]);
                }
                builder.append(']');
            }
    
            return builder.toString();
        }
    
       public static void main(String[] args) {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.start();
            String result = Formatter.format("My name is: %s. I was start from: %s. ", "Sean", "25/05/2012", "another value here");
            stopwatch.stop();
            System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
            System.out.println(result);
            stopwatch.reset();
            stopwatch.start();
            result = String.format("My name is: %s. I was start from: %s.", "Sean", "25/05/2012", "another value here");
            stopwatch.stop();
            System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
            System.out.println(result);
        }
    

    Tuesday, 14 August 2012

    Read line (or get line count) from JTextArea with wrap enabled

    public class Demo {
         JTextArea textArea = new JTextArea(text, 5, 50);
         textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
         textArea.setEditable(false);
         textArea.setLineWrap(true);
         textArea.setWrapStyleWord(true);
    
         private static String[] readLinesFromTextArea(JTextArea textArea, int limitRows) {
               String content = textArea.getText();
               String[] lines = new String[limitRows];
               Arrays.fill(lines, "");
               try {
                  int count = 0;
                  int offs = 0;
                  while (offs < content.length() && count < limitRows ) {
                     int end = Utilities.getRowEnd(textArea, offs);
                     String line = StringUtils.substring(content, offs, end);
                     lines[count++] = line;
                     offs = end + 1;
                  }
               } catch (BadLocationException e) {
                 log.error("Read line from 'Other' text area failed. Cause:\n", Throwables.getStackTraceAsString(e));
            }
    
            return lines;
        }
    }
    

    Monday, 6 August 2012

    Use Apache PDFBox convert PDF to image (support BMP,bmp,jpeg,wbmp,gif,png,JPG,jpg,JPEG,WBMP)

    • dependency
    • 
         org.apache.pdfbox
         pdfbox
         1.7.0
      
      
         org.bouncycastle
         bcprov-jdk15
         1.46
      
      
         org.bouncycastle
         bcmail-jdk15
         1.46
      
      
         org.apache.pdfbox
         fontbox
         1.7.0
                         
      
    • Code
    • import au.gov.nsw.police.nodi.common.CustomProperties;
      import org.apache.pdfbox.exceptions.CryptographyException;
      import org.apache.pdfbox.exceptions.InvalidPasswordException;
      import org.apache.pdfbox.pdmodel.PDDocument;
      import org.apache.pdfbox.pdmodel.PDPage;
      import org.apache.pdfbox.util.PDFImageWriter;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      
      import javax.imageio.*;
      import javax.imageio.metadata.IIOInvalidTreeException;
      import javax.imageio.metadata.IIOMetadata;
      import javax.imageio.metadata.IIOMetadataNode;
      import java.awt.*;
      import java.awt.image.BufferedImage;
      import java.awt.image.RenderedImage;
      import java.io.ByteArrayInputStream;
      import java.io.IOException;
      import java.util.Iterator;
      import java.util.List;
      
      import static com.google.common.base.Throwables.getStackTraceAsString;
      
      public class PDFToImage {
          private static final Logger log = LoggerFactory.getLogger(PDFToImage.class);
          private static final String STANDARD_METADATA_FORMAT = "javax_imageio_1.0";
          private static final String PDF_ENCRYPTED_PASSWORD = CustomProperties.getInstance().getProperty("pdf.from.esb.encrypted.password");
          private static final String IMAGE_FORMAT = "png";
          private static final int DEFAULT_IMAGE_RESOLUTION = 256;
      
          public static RenderedImage convertPdfOfGivenPageNumberToRenderImage(PDDocument document, int pageNumber) throws IOException {
              try {
                  decryptDocument(PDF_ENCRYPTED_PASSWORD, document);
      
                  int imageType = BufferedImage.TYPE_INT_RGB;
                  int resolution = DEFAULT_IMAGE_RESOLUTION;
                  try {
                      int screenResolution = Toolkit.getDefaultToolkit().getScreenResolution();
                      if (screenResolution > resolution) {
                          resolution = screenResolution;
                      }
                  } catch (HeadlessException e) {
                      log.debug("As it can't get the screen resolution. Use default resolution: {}", resolution);
                  }
      
                  List pages = document.getDocumentCatalog().getAllPages();
                  PDPage page = (PDPage) pages.get(pageNumber);
                  BufferedImage image = page.convertToImage(imageType, resolution);
                  return covertBufferedImageToRenderImage(image, IMAGE_FORMAT, resolution);
              } finally {
                  if (document != null) {
                      document.close();
                  }
              }
          }
      
          private static void decryptDocument(String password, PDDocument document) throws IOException {
              if (document.isEncrypted()) {
                  try {
                      document.decrypt(password);
                  } catch (InvalidPasswordException e) {
                      log.error("Error: The document is encrypted. Please provide correct PDF_ENCRYPTED_PASSWORD. Cause:\n{}", getStackTraceAsString(e));
                  } catch (CryptographyException e) {
                      log.error(getStackTraceAsString(e));
                  }
              }
          }
      
          private static RenderedImage covertBufferedImageToRenderImage(BufferedImage image, String imageFormat, int resolution) throws IOException {
              ImageWriter imageWriter = null;
              Iterator imageWriterIterator = ImageIO.getImageWritersByFormatName(imageFormat);
              if (imageWriterIterator.hasNext()) {
                  try {
                      imageWriter = imageWriterIterator.next();
                      ImageWriteParam writerParams = imageWriter.getDefaultWriteParam();
                      if (writerParams.canWriteCompressed()) {
                          writerParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                          // reset the compression type if overwritten by setCompressionMode
                          if (writerParams.getCompressionType() == null) {
                              writerParams.setCompressionType(writerParams.getCompressionTypes()[0]);
                          }
                          writerParams.setCompressionQuality(1.0f);
                      }
                      IIOMetadata meta = createMetadata(image, imageWriter, writerParams, resolution);
                      IIOImage iioImage = new IIOImage(image, null, meta);
                      return iioImage.getRenderedImage();
                  } finally {
                      if (imageWriter != null) {
                          imageWriter.dispose();
                      }
                  }
              }
      
              return null;
          }
      
          private static PDDocument loadPdfDocumentFromBytes(byte[] imageOfPdf) throws IOException {
              ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(imageOfPdf);
              return PDDocument.load(byteArrayInputStream);
      
          }
      
          private static PDDocument loadPdfDocumentFromFile(String fileName) throws IOException {
              return PDDocument.load(fileName);
          }
      
          //----------------------Copy from (start): org.apache.pdfbox.util.ImageIOUtil-----------------------------------
          private static IIOMetadata createMetadata(RenderedImage image, ImageWriter imageWriter, ImageWriteParam writerParams, int resolution) {
              ImageTypeSpecifier type;
              if (writerParams.getDestinationType() != null) {
                  type = writerParams.getDestinationType();
              } else {
                  type = ImageTypeSpecifier.createFromRenderedImage(image);
              }
              IIOMetadata meta = imageWriter.getDefaultImageMetadata(type, writerParams);
              return (addResolution(meta, resolution) ? meta : null);
          }
      
          private static boolean addResolution(IIOMetadata meta, int resolution) {
              if (!meta.isReadOnly() && meta.isStandardMetadataFormatSupported()) {
                  IIOMetadataNode root = (IIOMetadataNode) meta.getAsTree(STANDARD_METADATA_FORMAT);
                  IIOMetadataNode dimension = getChildNode(root, "Dimension");
                  IIOMetadataNode horizontalPixelSize = getChildNode(dimension, "HorizontalPixelSize");
                  String pixelSize = Double.toString(resolution / 25.4);
                  horizontalPixelSize.setAttribute("value", pixelSize);
      
                  IIOMetadataNode verticalPixelSize = getChildNode(dimension, "VerticalPixelSize");
                  verticalPixelSize.setAttribute("value", pixelSize);
                  try {
                      meta.mergeTree(STANDARD_METADATA_FORMAT, root);
                  } catch (IIOInvalidTreeException e) {
                      throw new RuntimeException("Cannot update image metadata: " + e.getMessage());
                  }
                  return true;
              }
              return false;
          }
      
      
          private static IIOMetadataNode getChildNode(IIOMetadataNode parentNode, String childNodeName) {
              NodeList nodes = parentNode.getChildNodes();
              for (int i = 0; i < nodes.getLength(); i++) {
                  Node child = nodes.item(i);
                  if (childNodeName.equals(child.getNodeName())) {
                      return (IIOMetadataNode) child;
                  }
              }
      
              return createChildNodeIfNotExist(parentNode, childNodeName);
          }
      
      
          private static IIOMetadataNode createChildNodeIfNotExist(IIOMetadataNode parentNode, String childNodeName) {
              IIOMetadataNode childNode = new IIOMetadataNode(childNodeName);
              parentNode.appendChild(childNode);
              return childNode;
          }
          //----------------------Copy from (end): org.apache.pdfbox.util.ImageIOUtil-----------------------------------
      
          public static void main(String[] args) throws IOException {
              String pdfFile = "c:/temp/test_avo.pdf";
              String outputPrefix = "c:/temp/";
      
              PDDocument document = loadPdfDocumentFromFile(pdfFile);
              int numberOfPages = document.getNumberOfPages();
              for (int i = 0; i < numberOfPages; i++) {
                  int pageNumber = i + 1;
                  RenderedImage renderedImage = convertPdfOfGivenPageNumberToRenderImage(document, pageNumber);
                  // render image to ui or
              }
      
              // if you just want to covert pdf file to image file, it's much easier.
              PDFImageWriter imageWriter = new PDFImageWriter();
              boolean success = imageWriter.writeImage(document, IMAGE_FORMAT, password, startPage, endPage, outputPrefix, BufferedImage.TYPE_INT_RGB, resolution);
              if (!success) {
                  System.err.println("Error: no writer found for image format '" + IMAGE_FORMAT + "'");
                  System.exit(1);
              }
          }
      
    • You can use following code to detected which image format is support
    • public static String getImageFormats() {
              StringBuffer retval = new StringBuffer();
              String[] formats = ImageIO.getReaderFormatNames();
              for (int i = 0; i < formats.length; i++) {
                  retval.append(formats[i]);
                  if (i + 1 < formats.length) {
                      retval.append(",");
                  }
              }
              return retval.toString();
          }
      
    • Dependencies can be download here
    • Others
    • Tiff image need native libary. You can find more information on java.net