Package net.xoetrope.swing.util

Source Code of net.xoetrope.swing.util.XGraphicsUtils

package net.xoetrope.swing.util;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.DataBufferInt;
import java.awt.image.Kernel;
import javax.swing.Timer;
import javax.swing.JComponent;

public class XGraphicsUtils
{
  protected int shadowSize = 5;
  protected float shadowOpacity = 0.5f;
  protected Color shadowColor = new Color(0x000000);
 
  public BufferedImage createShadow(BufferedImage original, int shadowSize)
  {
    int shadowWidth = original.getWidth() + shadowSize * 2;
    int shadowHeight = original.getHeight() + shadowSize * 2;

    BufferedImage shadow = new BufferedImage(shadowWidth, shadowHeight, BufferedImage.TYPE_INT_ARGB);
    // todo : copy the image as part of the drop shadow computing ... should be a 3x extra boost on my machine !!
    Graphics2D g = shadow.createGraphics();
    g.drawImage(original, shadowSize, shadowSize, null);
    g.dispose();

    applyShadow(shadow, shadowSize);

    return shadow;
  }

  public void applyShadow(BufferedImage dst, int shadowSize)
  {
    int dstWidth = dst.getWidth();
    int dstHeight = dst.getHeight();

    int left = (shadowSize - 1) >> 1;
    int right = shadowSize - left;
    int xStart = left;
    int xStop = dstWidth - right;
    int yStart = left;
    int yStop = dstHeight - right;

    int shadowRgb = shadowColor.getRGB() & 0x00FFFFFF;

    int[] aHistory = new int[shadowSize];
    int historyIdx = 0;

    int aSum;

    int[] dataBuffer = ((DataBufferInt)dst.getRaster().getDataBuffer()).getData();
    int lastPixelOffset = right * dstWidth;
    float sumDivider = shadowOpacity / shadowSize;

    // horizontal pass
    for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
      aSum = 0;
      historyIdx = 0;
      for (int x = 0; x < shadowSize; x++, bufferOffset++) {
        int a = dataBuffer[bufferOffset] >>> 24;
        aHistory[x] = a;
        aSum += a;
      }

      bufferOffset -= right;

      for (int x = xStart; x < xStop; x++, bufferOffset++) {
        int a = (int)(aSum * sumDivider);
        dataBuffer[bufferOffset] = a << 24 | shadowRgb;

        // substract the oldest pixel from the sum
        aSum -= aHistory[historyIdx];

        // get the lastest pixel
        a = dataBuffer[bufferOffset + right] >>> 24;
        aHistory[historyIdx] = a;
        aSum += a;

        if (++historyIdx >= shadowSize)
          historyIdx -= shadowSize;
      }
    }

    // vertical pass
    for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
      aSum = 0;
      historyIdx = 0;
      for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
        int a = dataBuffer[bufferOffset] >>> 24;
        aHistory[y] = a;
        aSum += a;
      }

      bufferOffset -= lastPixelOffset;

      for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
        int a = (int)(aSum * sumDivider);
        dataBuffer[bufferOffset] = a << 24 | shadowRgb;

        // substract the oldest pixel from the sum
        aSum -= aHistory[historyIdx];

        // get the lastest pixel
        a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
        aHistory[historyIdx] = a;
        aSum += a;

        if (++historyIdx >= shadowSize)
          historyIdx -= shadowSize;
      }
    }
  }

  public BufferedImage createDropShadow(BufferedImage image)
  {
    if ( image != null ) {
      BufferedImage shadow = new BufferedImage(image.getWidth(),
                                               image.getHeight(),
                                               BufferedImage.TYPE_INT_ARGB);
      BufferedImage shadowMask = createShadowMask( image );
      getBlurOp( shadowSize ).filter( shadowMask, shadow );
      return shadow;
    }
   
    return null;
  }

  public void applyBlur(BufferedImage src, BufferedImage dst, int shadowSize)
  {
    if (shadowSize == 1) {
      Graphics2D g = dst.createGraphics();
      g.drawImage(src, 0, 0, null);
      g.dispose();
      return;
    }

    int srcWidth = src.getWidth();
    int srcHeight = src.getHeight();

    int left = (shadowSize - 1) >> 1;
    int right = shadowSize - left;
    int xStart = left;
    int xStop = srcWidth - right;
    int yStart = left;
    int yStop = srcHeight - right;

    int[] aHistory = new int[shadowSize];
    int[] rHistory = new int[shadowSize];
    int[] vHistory = new int[shadowSize];
    int[] bHistory = new int[shadowSize];
    int historyIdx = 0;

    int aSum;
    int rSum;
    int vSum;
    int bSum;

    // horizontal pass
    for (int y = 0; y < srcHeight; y++) {
      aSum = 0;
      rSum = 0;
      vSum = 0;
      bSum = 0;
      historyIdx = 0;
      for (int x = 0; x < shadowSize; x++) {
        int argb = src.getRGB(x, y);
        int a = (argb & 0xFF000000) >>> 24;
        int r = (argb & 0x00FF0000) >>> 16;
        int v = (argb & 0x0000FF00) >>> 8;
        int b = (argb & 0x000000FF);
        aHistory[x] = a;
        rHistory[x] = r;
        vHistory[x] = v;
        bHistory[x] = b;
        aSum += a;
        rSum += r;
        vSum += v;
        bSum += b;
      }

      for (int x = xStart; x < xStop; x++) {
        int a = aSum / shadowSize;
        int r = rSum / shadowSize;
        int v = vSum / shadowSize;
        int b = bSum / shadowSize;
        dst.setRGB(x, y, a << 24 | r << 16 | v << 8 | b);

        // substract the oldest pixel from the sum
        aSum -= aHistory[historyIdx];
        rSum -= rHistory[historyIdx];
        vSum -= vHistory[historyIdx];
        bSum -= bHistory[historyIdx];

        // get the lastest pixel
        int argb = src.getRGB(x + right, y);
        a = (argb & 0xFF000000) >>> 24;
        r = (argb & 0x00FF0000) >>> 16;
        v = (argb & 0x0000FF00) >>> 8;
        b = (argb & 0x000000FF);

        aHistory[historyIdx] = a;
        rHistory[historyIdx] = r;
        vHistory[historyIdx] = v;
        bHistory[historyIdx] = b;

        aSum += a;
        rSum += r;
        vSum += v;
        bSum += b;

        if (++historyIdx >= shadowSize)
          historyIdx -= shadowSize;
      }
    }

    // vertical pass
    for (int x = 0; x < srcWidth; x++) {
      aSum = 0;
      rSum = 0;
      vSum = 0;
      bSum = 0;
      historyIdx = 0;
      for (int y = 0; y < shadowSize; y++) {
        int argb = dst.getRGB(x, y);
        int a = (argb & 0xFF000000) >>> 24;
        int r = (argb & 0x00FF0000) >>> 16;
        int v = (argb & 0x0000FF00) >>> 8;
        int b = (argb & 0x000000FF);
        aHistory[y] = a;
        rHistory[y] = r;
        vHistory[y] = v;
        bHistory[y] = b;
        aSum += a;
        rSum += r;
        vSum += v;
        bSum += b;
      }

      for (int y = yStart; y < yStop; y++) {
        int a = aSum / shadowSize;
        int r = rSum / shadowSize;
        int v = vSum / shadowSize;
        int b = bSum / shadowSize;
        dst.setRGB(x, y, a << 24 | r << 16 | v << 8 | b);

        // substract the oldest pixel from the sum
        aSum -= aHistory[historyIdx];
        rSum -= rHistory[historyIdx];
        vSum -= vHistory[historyIdx];
        bSum -= bHistory[historyIdx];

        // get the lastest pixel
        int argb = dst.getRGB(x, y + right);
        a = (argb & 0xFF000000) >>> 24;
        r = (argb & 0x00FF0000) >>> 16;
        v = (argb & 0x0000FF00) >>> 8;
        b = (argb & 0x000000FF);

        aHistory[historyIdx] = a;
        rHistory[historyIdx] = r;
        vHistory[historyIdx] = v;
        bHistory[historyIdx] = b;

        aSum += a;
        rSum += r;
        vSum += v;
        bSum += b;

        if (++historyIdx >= shadowSize)
          historyIdx -= shadowSize;
      }
    }
  }

  public BufferedImage createShadowMask(BufferedImage image)
  {
    BufferedImage mask = new BufferedImage(image.getWidth(),
                                           image.getHeight(),
                                           BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2d = mask.createGraphics();
    g2d.drawImage(image, 0, 0, null);
    // Ar = As*Ad - Cr = Cs*Ad   --- By using this composite we can extract the alpha layer from the picture ...
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, shadowOpacity));
    g2d.setColor(shadowColor);
    g2d.fillRect(0, 0, image.getWidth(), image.getHeight())// this will fill with the shadowColor and alpha=1.0f
    g2d.dispose();

    return mask;
  }

  public ConvolveOp getBlurOp(int size)
  {
    float[] data = new float[size * size];
    float value = 1 / (float)(size * size);
    for (int i = 0; i < data.length; i++)
      data[i] = value;
   
    return new ConvolveOp(new Kernel(size, size, data));
  }
 
  /**
   * Briefly vibrate the component by changing it's position
   * @param comp the component to move.
   */
  public static void vibrate( final JComponent comp )
  {
    final Point location = comp.getLocation();
    final int duration = 500;
    final double distance = 5.0;
    final double cycles = 50.0;
    final long startTime = System.currentTimeMillis();
   
    final Timer shakeTimer = new Timer( 10, new ActionListener() {
      public void actionPerformed( ActionEvent e )
      {
        long elapsedTime = System.currentTimeMillis() - startTime;
        double offset = ( elapsedTime % cycles ) / cycles;
        double angle = offset * Math.PI * 2.0;
       
        int shakeX = (int)( Math.sin( angle ) * distance  + location.x );
        comp.setLocation( shakeX, location.y );
        comp.repaint();
       
        if ( elapsedTime >= duration )
          stopShake( (Timer)e.getSource(), comp );
      }
     
      public void stopShake( Timer t, JComponent comp )
      {
         t.stop();
         comp.setLocation( location );
         comp.repaint();
      }
    });   
    shakeTimer.start();
  }
}
TOP

Related Classes of net.xoetrope.swing.util.XGraphicsUtils

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.