Package com.xeiam.xchart

Source Code of com.xeiam.xchart.BitmapEncoder

/**
* Copyright 2011 - 2014 Xeiam LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.xeiam.xchart;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;

/**
* A helper class with static methods for saving Charts as bitmaps
*
* @author timmolter
*/
public final class BitmapEncoder {

  /**
   * Constructor - Private constructor to prevent instantiation
   */
  private BitmapEncoder() {

  }

  public enum BitmapFormat {
    PNG, JPG, BMP, GIF;
  }

  /**
   * Save a Chart as an image file
   *
   * @param chart
   * @param fileName
   * @param bitmapFormat
   * @throws IOException
   */
  public static void saveBitmap(Chart chart, String fileName, BitmapFormat bitmapFormat) throws IOException {

    BufferedImage bufferedImage = getBufferedImage(chart);

    OutputStream out = new FileOutputStream(fileName + "." + bitmapFormat.toString().toLowerCase());
    ImageIO.write(bufferedImage, bitmapFormat.toString().toLowerCase(), out);
    out.close();
  }

  /**
   * Save a chart as a PNG with a custom DPI. The default DPI is 72, which is fine for displaying charts on a computer monitor, but for printing charts, a DPI of around 300 is much better.
   *
   * @param chart
   * @param fileName
   * @param DPI
   * @throws IOException
   */
  public static void saveBitmapWithDPI(Chart chart, String fileName, BitmapFormat bitmapFormat, int DPI) throws IOException {

    double scaleFactor = DPI / 72.0;

    BufferedImage bufferedImage = new BufferedImage((int) (chart.getWidth() * scaleFactor), (int) (chart.getHeight() * scaleFactor), BufferedImage.TYPE_INT_RGB);

    Graphics2D graphics2D = bufferedImage.createGraphics();

    AffineTransform at = graphics2D.getTransform();
    at.scale(scaleFactor, scaleFactor);
    graphics2D.setTransform(at);

    chart.paint(graphics2D, chart.getWidth(), chart.getHeight());
    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(bitmapFormat.toString().toLowerCase());
    if (writers.hasNext()) {
      ImageWriter writer = writers.next();
      // instantiate an ImageWriteParam object with default compression options
      ImageWriteParam iwp = writer.getDefaultWriteParam();

      ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
      IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, iwp);
      if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
        throw new IllegalArgumentException("It is not possible to set the DPI on a bitmap with " + bitmapFormat + " format!! Try another format.");
      }

      setDPI(metadata, DPI);

      File file = new File(fileName + "." + bitmapFormat.toString().toLowerCase());
      FileImageOutputStream output = new FileImageOutputStream(file);
      writer.setOutput(output);
      IIOImage image = new IIOImage(bufferedImage, null, metadata);
      writer.write(null, image, iwp);
      writer.dispose();
    }
  }

  /**
   * Sets the metadata correctly
   *
   * @param metadata
   * @param DPI
   * @throws IIOInvalidTreeException
   */
  private static void setDPI(IIOMetadata metadata, int DPI) throws IIOInvalidTreeException {

    // for PNG, it's dots per millimeter
    double dotsPerMilli = 1.0 * DPI / 10 / 2.54;

    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);
  }

  /**
   * Save a Chart as a JPEG file
   *
   * @param chart
   * @param fileName
   * @param quality - a float between 0 and 1 (1 = maximum quality)
   * @throws FileNotFoundException
   * @throws IOException
   */
  public static void saveJPGWithQuality(Chart chart, String fileName, float quality) throws FileNotFoundException, IOException {

    BufferedImage bufferedImage = getBufferedImage(chart);

    Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
    ImageWriter writer = iter.next();
    // instantiate an ImageWriteParam object with default compression options
    ImageWriteParam iwp = writer.getDefaultWriteParam();
    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    iwp.setCompressionQuality(quality);
    File file = new File(fileName);
    FileImageOutputStream output = new FileImageOutputStream(file);
    writer.setOutput(output);
    IIOImage image = new IIOImage(bufferedImage, null, null);
    writer.write(null, image, iwp);
    writer.dispose();
  }

  /**
   * Generates a byte[] for a given chart, PNG compressed
   *
   * @param chart
   * @return a byte[] for a given chart, PNG compressed
   * @throws IOException
   */
  public static byte[] getBitmapBytes(Chart chart, BitmapFormat bitmapFormat) throws IOException {

    BufferedImage bufferedImage = getBufferedImage(chart);

    byte[] imageInBytes = null;

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(bufferedImage, bitmapFormat.toString().toLowerCase(), baos);
    baos.flush();
    imageInBytes = baos.toByteArray();
    baos.close();

    return imageInBytes;
  }

  public static BufferedImage getBufferedImage(Chart chart) {

    BufferedImage bufferedImage = new BufferedImage(chart.getWidth(), chart.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = bufferedImage.createGraphics();
    chart.paint(graphics2D);
    return bufferedImage;
  }

}
TOP

Related Classes of com.xeiam.xchart.BitmapEncoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.