title: Write PNG file with less disk size in Java
body: <p>I have a <code>BufferedImage</code>: </p>
  
  <pre><code>BufferedImage bi = new BufferedImage(14400, 14400, BufferedImage.TYPE_INT_ARGB);
  </code></pre>
  
  <p>I have saved this image to a PNG file using the following code:</p>
  
  <pre><code>public static void saveGridImage(BufferedImage sourceImage, int DPI,
              File output) throws IOException {
          output.delete();
  
          final String formatName = "png";
  
          for (Iterator&lt;ImageWriter&gt; iw = ImageIO
                  .getImageWritersByFormatName(formatName); iw.hasNext();) {
              ImageWriter writer = iw.next();
              ImageWriteParam writeParam = writer.getDefaultWriteParam();
              ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier
                      .createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
              IIOMetadata metadata = writer.getDefaultImageMetadata(
                      typeSpecifier, writeParam);
              if (metadata.isReadOnly()
                      || !metadata.isStandardMetadataFormatSupported()) {
                  continue;
              }
  
              setDPI(metadata, DPI);
  
              final ImageOutputStream stream = ImageIO
                      .createImageOutputStream(output);
              try {
                  writer.setOutput(stream);
                  writer.write(metadata,
                          new IIOImage(sourceImage, null, metadata), writeParam);
              } finally {
                  stream.close();
              }
              break;
          }
      }
  
      public static void setDPI(IIOMetadata metadata, int DPI)
              throws IIOInvalidTreeException {
  
          double INCH_2_CM = 2.54;
  
          // for PNG, it's dots per millimeter
          double dotsPerMilli = 1.0 * DPI / 10 / INCH_2_CM;
  
          IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
          horiz.setAttribute("value", Double.toString(dotsPerMilli));
  
          IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
          vert.setAttribute("value", Double.toString(dotsPerMilli));
  
          IIOMetadataNode dim = new IIOMetadataNode("Dimension");
          dim.appendChild(horiz);
          dim.appendChild(vert);
  
          IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
          root.appendChild(dim);
  
          metadata.mergeTree("javax_imageio_1.0", root);
      }
  </code></pre>
  
  <p>When the code executes it creates an PNG file with 400 DPI and Disk Size of <strong>168 MB</strong>; this is too much.</p>
  
  <p>Is there any way or parameters I can use to save a smaller PNG?</p>
  
  <p>Before, I had a 1.20 GB TIFF file, and when I converted it to PNG using imagemagick at 400 DPI, the resulting file size was only 700 KB.</p>
  
  <p>So, I think I might be able to save the above file smaller.</p>
  
  <p><strong>Can pngj help me? Because I now have a png file which I can read in pngj library.</strong></p>