Package com.zesped.util

Source Code of com.zesped.util.Picture

package com.zesped.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;

import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.renderable.ParameterBlock;
import java.awt.color.ColorSpace;
import java.awt.Transparency;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.media.jai.PlanarImage;
import javax.media.jai.ParameterBlockJAI;

import com.knowgate.misc.Base64Decoder;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.zesped.Log;

/**
* <p>Simple imaging transformations</p>
* @author Sergio Montoro Ten
* @version 2.1
*/

public class Picture {

  private int iImagingLibrary;

  private MediaTracker mediaTracker;

  private Image oImg;

  /**
   * Create empty Picture, use JAI imaging routines.
   */
  public Picture() {
    iImagingLibrary = USE_JAI;
    mediaTracker = null;
  }

  /**
   * Create empty Picture.
   * @param iLibraryCode Imaging library to use. Either USE_AWT or USE_JAI.
   * @throws IllegalArgumentException
   */
  public Picture(int iLibraryCode) throws IllegalArgumentException {
    setImagingLibrary(iLibraryCode);
    mediaTracker = null;
  }

  /**
   * Load Picture directly from a Java AWT abstract Image
   * @param oAWTImage java.awt.Image object
   * @param sPath Optional. Path to image file name.
   * @param iLibraryCode Imaging library to use. Either USE_AWT or USE_JAI.
   */
  public Picture(Image oAWTImage, String sPath, int iLibrary) {
    iImagingLibrary = iLibrary;
    mediaTracker = null;
    oImg = oAWTImage;
  }

  //----------------------------------------------------------------------------

  /**
   * <p>Set imaging library to use.</p>
   * On many systems it is necessary to have X-Windows started for being able to
   * use AWT imaging routines.<br>
   * @param iLibraryCode USE_AWT or USE_JAI
   * @see http://java.sun.com/products/java-media/jai/
   * @see http://java.sun.com/j2se/1.4.2/docs/api/
   */
  public void setImagingLibrary (int iLibraryCode) {
    if (iLibraryCode!=USE_AWT && iLibraryCode!=USE_JAI)
      throw new IllegalArgumentException("Imaging library code must be Image.USE_AWT or Image.USE_JAI");

    iImagingLibrary = iLibraryCode;
  } // setImagingLibrary

  //----------------------------------------------------------------------------

  /**
   * <p>Get active imaging library.</p>
   * @return USE_AWT or USE_JAI
   */
  public int getImagingLibrary() {
    return iImagingLibrary;
  } // getImagingLibrary

  //----------------------------------------------------------------------------

  /*
  public String getImageCodec() {
    String sCodec;
    String sType = getImageType();

    if (sType.equalsIgnoreCase("jpg"))
      sCodec = "jpeg";
    else if (sType.equalsIgnoreCase("tif"))
      sCodec = "tiff";
    else
      sCodec = sType;

    return sCodec;
  }

*/
 
  //----------------------------------------------------------------------------

  private int unsigned (byte by) {
    final byte MinusOne = -1;

    return (by<0) ? ((int) (by*MinusOne))+128 : (int) by;
  }

  // ----------------------------------------------------------

  private int[] dimensionsJAI(byte[] byImg, String sCodec)
    throws IOException, NullPointerException {

    int[] aRetVal = new int[2];

    RenderedImage oImg;
    ImageDecoder oDecoder;

    oDecoder = ImageCodec.createImageDecoder(sCodec, new ByteArrayInputStream(byImg), null);

    oImg = oDecoder.decodeAsRenderedImage();

    aRetVal[0] = oImg.getWidth();
    aRetVal[1] = oImg.getHeight();

    return aRetVal;
  } // dimensionsJAI

  // ----------------------------------------------------------

  /**
   * <p>Get image dimensions.</p>
   * Dimensions are stored at dm_width and dm_height properties.<br>
   * Only GIF 89a and JPG/JPEG images are supported
   * @return <b>true</b> if dimensions where successfully computed,
   * <b>false</b> if routine was unable to recognize file format.
   * @throws IOException
   * @throws ArrayIndexOutOfBoundsException
   * @throws NullPointerException
   * @throws UnsatisfiedLinkError When JAI native libraries (*_jai.so) are not
   * installed Sun JAI tries to use AWT which is slower but more compatible.
   * Some libraries of AWT are requiered. Particularly from Fedora Core 2:<br>
   * xorg-x11-devel (contains libXp.so, requiered by libawt.so),
   * fontconfig, fontconfig-devel, xorg-x11-libs, xorg-x11-libs-data, xorg-x11-Mesa-libGL
   */
  public int[] dimensions(byte[] byImg, String sCodec)
    throws IOException, FileNotFoundException, ArrayIndexOutOfBoundsException,
           UnsatisfiedLinkError, NullPointerException {

      int[] aRetVal = new int[2];
      int iFound;
      byte by;

      Log.out.debug("Begin ThumbnailCreator.dimensions("+sCodec+")");
     
      if (USE_JAI==iImagingLibrary)

      try {
          aRetVal = dimensionsJAI(byImg, sCodec);
        }
          catch (IOException ioe) { aRetVal = null; }

      else

      if (sCodec.equals("gif")) {
          aRetVal[0] = (unsigned(byImg[7]))*256 + (unsigned(byImg[6]));
          aRetVal[1] = (unsigned(byImg[9]))*256 + (unsigned(byImg[8]));

        } // fi (sType==GIF)

        else if (sCodec.equals("jpeg")) {

          final int iTotal = byImg.length;

          iFound = 0;

          for (int iPos=21;
               iPos<iTotal-10;
               iPos = (2 + iPos + (unsigned(byImg[iPos + 1]) * 256 + unsigned(byImg[iPos+2]))) ) {

            by = byImg[iPos];
            if ((by>=0xC0 && by<=0xC3) || (by>=0xC5 && by<=0xC7) || (by>=0xC9 && by<=0xCB) || (by>=0xCD && by<=0xCF)) {
              iFound = iPos;
              break;
            }
          } // next (iPos)

          if (0!=iFound) {
            aRetVal[0] = (unsigned(byImg[iFound + 6]) * 256 + unsigned(byImg[iFound + 7]));
          aRetVal[1] = (unsigned(byImg[iFound + 4]) * 256 + unsigned(byImg[iFound + 5]));
          }
          else {
            aRetVal=null;
          }
        }
        else
          aRetVal=null;

      Log.out.debug("End ThumbnailCreator.dimensions() : " + aRetVal);
     
    return aRetVal;
  } // dimensions

  // ----------------------------------------------------------

  private void drawAWTImage(byte[] aImgSource, OutputStream outStr, int iThumbWidth, int iThumbHeight, float fQuality) throws IOException, InstantiationException, InterruptedException {

    Frame awtFrame;
    JPEGImageEncoder encoder;
    JPEGEncodeParam param;
    BufferedImage thumbImage;
    Graphics2D graphics2D;

    oImg = Toolkit.getDefaultToolkit().createImage(aImgSource);

    int iImageWidth = oImg.getWidth(null);
    int iImageHeight = oImg.getHeight(null);

    double thumbRatio = ((double) iThumbWidth) / ((double) iThumbHeight);
    double imageRatio = ((double) iImageWidth) / ((double) iImageHeight);

    if (thumbRatio < imageRatio)
      iImageHeight = (int)(iThumbWidth / imageRatio);
    else
      iThumbWidth = (int)(iThumbHeight * imageRatio);

    if (null==mediaTracker) {

      try {
        awtFrame = new Frame();
      } catch (Exception e) { throw new InstantiationException("Cannot instantiate java.awt.Frame " + (e.getMessage()!=null ? e.getMessage() : "")); }

      mediaTracker = new MediaTracker(awtFrame);
    } // fi (mediaTracker)

    mediaTracker.addImage(oImg, 0);
    mediaTracker.waitForID(0);

    // draw original image to thumbnail image object and
    // scale it to the new size on-the-fly
    thumbImage = new BufferedImage(iThumbWidth, iThumbHeight, BufferedImage.TYPE_INT_RGB);

    graphics2D = thumbImage.createGraphics();
    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.drawImage(oImg, 0, 0, iThumbWidth, iThumbHeight, null);
    graphics2D.dispose();

    encoder = JPEGCodec.createJPEGEncoder(outStr);
    param = encoder.getDefaultJPEGEncodeParam(thumbImage);

  // javax.imageio.plugins.jpeg.JPEGHuffmanTable t;
  // javax.imageio.plugins.jpeg.JPEGQTable q;
 
    fQuality = Math.max(0, Math.min(fQuality, 100));
    if (fQuality>1)
      param.setQuality(fQuality / 100.0f, false);
    else
      param.setQuality(fQuality, false);

    encoder.setJPEGEncodeParam(param);

    encoder.encode(thumbImage);

    thumbImage.flush();

    mediaTracker.removeImage(oImg, 0);

  } // drawAWTImage()


  // ----------------------------------------------------------

  private void drawJAIImage(String sCodec, InputStream imgSrc, OutputStream outStr, int iThumbWidth, int iThumbHeight, float fQuality)
    throws IOException, InterruptedException, NullPointerException, IllegalArgumentException {

    RenderedImage oRenderedImg;
    PlanarImage oPlI;
    RenderedOp oScI;
    ParameterBlock oBlk;
    ImageEncoder oImgEnc;
    ImageDecoder oDecoder;

    Log.out.debug("Begin Picture.drawJAIImage("+sCodec+","+String.valueOf(iThumbWidth)+","+String.valueOf(iThumbHeight)+")");
   
    oDecoder = com.sun.media.jai.codec.ImageCodec.createImageDecoder(sCodec, imgSrc, null);

    oRenderedImg = oDecoder.decodeAsRenderedImage();

    if (sCodec.equals("gif")) {
      // Increase color depth to 16M RGB
      try {
        javax.media.jai.ImageLayout layout = new javax.media.jai.ImageLayout();

        ColorModel cm = new ComponentColorModel (ColorSpace.getInstance(ColorSpace.CS_sRGB),
                                                 new int[] {8,8,8}, false, false,
                                                 Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
        layout.setColorModel(cm);
        layout.setSampleModel(cm.createCompatibleSampleModel(oRenderedImg.getWidth(),oRenderedImg.getHeight()));
        RenderingHints hints = new RenderingHints(javax.media.jai.JAI.KEY_IMAGE_LAYOUT, layout);
        ParameterBlockJAI pb = new ParameterBlockJAI( "format" );
        pb.addSource( oRenderedImg );
        oRenderedImg = javax.media.jai.JAI.create( "format", pb, hints );
      } catch (IllegalArgumentException iae) {
      }
      // End increase color depth
    } // gif

    oPlI = PlanarImage.wrapRenderedImage(oRenderedImg);

    int iImageWidth = oPlI.getWidth();
    int iImageHeight = oPlI.getHeight();

    float thumbRatio = ((float) iThumbWidth) / ((float) iThumbHeight);

    float imageRatio = ((float) iImageWidth) / ((float) iImageHeight);

    if (thumbRatio < imageRatio)
      iThumbHeight = (int)(iThumbWidth / imageRatio);
    else
      iThumbWidth = (int)(iThumbHeight * imageRatio);

    float scaleW = ((float) iThumbWidth) / ((float) iImageWidth);

    float scaleH = ((float) iThumbHeight) / ((float) iImageHeight);

    oBlk = new ParameterBlock();

    oBlk.addSource(oPlI);

    oBlk.add(scaleW);
    oBlk.add(scaleH);
    oBlk.add(0.0f);
    oBlk.add(0.0f);
    oBlk.add(new javax.media.jai.InterpolationBilinear());

    oScI = JAI.create("scale", oBlk, null); // scale image NOW !
       
    oImgEnc = ImageCodec.createImageEncoder( "jpeg", outStr, null );
    if (null==oImgEnc) {
      throw new NullPointerException("Cannot create ImageEncoder for jpeg");
    }
    else {
      oImgEnc.encode( oScI ); // write encoded data to given output stream
      oImgEnc =null;
    }

    Log.out.debug("End Picture.drawJAIImage()");

  } // drawJAIImage

  // ----------------------------------------------------------
  /**
   * <p>Resample image.</p>
   * @param sInputPath Input file path
   * @param iThumbWidth Desired width
   * @param iThumbHeight Desired height
   * @param fQuality JPG Quality [1..100]
   * @return Byte array holding the generated JPEG image
   * @throws NullPointerException
   * @throws IOException
   * @throws InterruptedException
   * @throws InstantiationException
   */
  public byte[] createThumbBitmap(byte[] aBytes, String sCodec, int iThumbWidth, int iThumbHeight, float fQuality)
    throws NullPointerException, IOException, InterruptedException, InstantiationException {

    ByteArrayOutputStream outStr = new ByteArrayOutputStream(iThumbWidth*iThumbHeight*3+1024);

    if (USE_AWT==iImagingLibrary)
      drawAWTImage (aBytes, outStr, iThumbWidth, iThumbHeight, fQuality);
    else
      drawJAIImage (sCodec, new ByteArrayInputStream(aBytes), outStr, iThumbWidth, iThumbHeight, fQuality);

    return outStr.toByteArray();
  } // createThumbBitmap()

  // ----------------------------------------------------------
  /**
   * <p>Resample image.</p>
   * @param sInputPath Input file path
   * @param sOutputPath File path where generated JPEG shall be saved.
   * @param iThumbWidth Desired width
   * @param iThumbHeight Desired height
   * @param fQuality JPG Quality [1..100]
   * @throws NullPointerException
   * @throws IOException
   * @throws InstantiationException
   * @throws InterruptedException
   * @throws InstantiationException
   */

  public void createThumbFile(byte[] aBytes, String sCodec, String sOutputPath, int iThumbWidth, int iThumbHeight, float fQuality)
    throws NullPointerException, InterruptedException, IOException, InstantiationException {
 
    FileOutputStream outStr = new FileOutputStream(sOutputPath);

    if (USE_AWT==iImagingLibrary)
      drawAWTImage (aBytes, outStr, iThumbWidth, iThumbHeight, fQuality);
    else
      drawJAIImage (sCodec, new ByteArrayInputStream(aBytes), outStr, iThumbWidth, iThumbHeight, fQuality);

    outStr.close();
    outStr=null;

  } // createThumbFile()

  // ----------------------------------------------------------

  /**
   * <p>Encode Image and write it to an OutputStream</p>
   * @param oOut OutputStream
   * @throws NullPointerException If underlying java.awt.Image object is <b>null</b>
   * @throws IOException
   * @throws InstantiationException
   * @throws InterruptedException
   */
  public void write(OutputStream oOut, String sCodec)
    throws NullPointerException,IOException,InstantiationException,InterruptedException {

    if (null==oImg) {
      throw new NullPointerException("java.awt.Image is null");
    }

    ImageEncoder oEnc = ImageCodec.createImageEncoder(sCodec, oOut, null);

    if (null==oEnc) {

      throw new InstantiationException("ImageCodec.createImageEncoder("+sCodec+")");
    }
    if (USE_JAI==iImagingLibrary) {

      RenderedImage oRImg = javax.media.jai.JAI.create("awtimage", oImg);

      if (null==oEnc) {
        throw new InstantiationException("JAI.create(awtimage, "+oImg.getClass().getName()+")");
      }

      oEnc.encode(oRImg);
    }
    else {
      int iImageWidth = oImg.getWidth(null);
      int iImageHeight = oImg.getHeight(null);

      if (null==mediaTracker) {

        Frame awtFrame = null;
        try {
          awtFrame = new Frame();
        } catch (Exception e) { throw new InstantiationException("Cannot instantiate java.awt.Frame " + (e.getMessage()!=null ? e.getMessage() : "")); }

        mediaTracker = new MediaTracker(awtFrame);
      } // fi (mediaTracker)

      mediaTracker.addImage(oImg, 0);
      mediaTracker.waitForID(0);

      BufferedImage oBImg = new BufferedImage(iImageWidth, iImageHeight, BufferedImage.TYPE_INT_RGB);

      Graphics2D graphics2D = oBImg.createGraphics();
      graphics2D.drawImage(oImg, 0, 0, iImageWidth, iImageHeight, null);
      graphics2D.dispose();

      oEnc.encode(oBImg);

      mediaTracker.removeImage(oImg,0);
    }
  }

  // ----------------------------------------------------------

  /**
   * <p>Get a transparent GIF image that can be served throught a JSP page</p>
   * Use code like
   * response.setContentType("image/gif");
   * OutputStream oOut = response.getOutputStream();
   * oOut.write(Image.blankGIF());
   * oOut.flush();
   * @since 3.0
   * @return byte[]
   */
  public static byte[] blankGIF() {
    return Base64Decoder.decodeToBytes("R0lGODlhAQABAJEAAAAAAP///////wAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw==");
  }

  // **********************************************************
  // Public Constants

  public static final int USE_AWT = 0;
  public static final int USE_JAI = 1;

  public static final String CODEC_JPEG ="jpeg";
  public static final String CODEC_TIFF ="tiff";
  public static final String CODEC_GIF ="gif";
 
} // Image
TOP

Related Classes of com.zesped.util.Picture

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.