gisbya's Warp class
here's the (formatted) code:
import java.awt.*;
import java.awt.Component.*;
import java.awt.image.*;
import java.util.Random;
import java.awt.geom.AffineTransform;
/**
*
* @author gisbya
* @version
*/
publicclass Warpextends java.awt.Component{
/*
* PROPERTIES ETC
*/
private BufferedImage logical;// Work image
private BufferedImage virtual;// Work image
private Graphics2D gLogical;
private Graphics2D gVirtual;
private Random mRnd =new Random(0);
privateboolean keepgoing =true;
privateboolean newframe =false;
private Color[] rCol =new Color[255];
// Rotation transformation...
private AffineTransform xform;
// Blur filter...
private Kernel myKernel;
private ConvolveOp simpleBlur;
// Property: BlurOn - Cause Warp effect to use blur filter (major processing!).
privateboolean mBlurOn =true;
publicboolean isBlurOn(){
return mBlurOn;
}
publicvoid toggleBlurOn(){
if (!mBlurOn){
mBlurOn =true;
}else{
mBlurOn =false;
}
}
// Property: Reset - Cause Warp effect to reset itself.
privateboolean mReset =false;// If true, reset warp effect.
publicboolean resetPending(){
return mReset;
}
publicvoid setReset(boolean r){
mReset = r;
// If reset requested, initialise...
if (mReset){
initWarp();
mReset =false;// all done
}
}
publicvoid reset(){
setReset(true);
}
// Property: Original Image (Basis for warp to start (blur, zoom , etc).
private BufferedImage mOriginalImage;
publicvoid setOriginalImage(BufferedImage g){
mOriginalImage = g;
}
public BufferedImage getOriginalImage(){
return mOriginalImage;
}
// Property: Current Frame
private BufferedImage mFrame;
public BufferedImage getFrame(){
return mFrame;
}
// Graphics2D context for mFrame
private Graphics2D mFrameGraphics;
public Graphics2D getFrameGraphics(){
return mFrameGraphics;
}
// Property: Warp effect work area size width
privateint mWidth = 200;
publicvoid setWarpWidth(int w){
mWidth = w;
// Width has changed, so cause a reset...
this.reset();
}
publicint getWarpWidth(){
return mWidth;
}
// Property: Warp effect work area size height
privateint mHeight = 100;
publicvoid setWarpHeight(int h){
mHeight = h;
// Width has changed, so cause a reset...
this.reset();
}
publicint getWarpHeight(){
return mHeight;
}
// Property: Warp effect velocity
privateint mVelocity = 0;
publicvoid setVelocity(int a){
mVelocity = a;
}
publicint getVelocity(){
return mVelocity;
}
// Property: Warp effect velocity increment
privateint mVelocityInc = 1;
publicvoid setVelocityInc(int a){
mVelocityInc = a;
}
publicint getVelocityInc(){
return mVelocityInc;
}
// Property: Light randomisation effect
privateint mLightDensity = 16;
publicvoid setLightDensity(int a){
mLightDensity = a;
}
publicint getLightDensity(){
return mLightDensity;
}
// Set width and height at the same time...
publicvoid setWarpBounds(int width,int height){
mWidth = width;
mHeight = height;
this.reset();
}
/** Creates new warp */
public Warp(){
super();
// Set up an Array of colors...
for (int i = 0; i < 255; i++){
rCol =new Color(255, i >> 3, i);
}
// Initialise...
initWarp();
}
/*
* INTERNAL METHODS (To this bean)
*/
/**
* Used to initialise a "warp" effect. Recreates all off-screen
* images and maps OriginalImage on to the first frame.
*
* Make sure OriginalImage, Width and Height are set to desired
* values before using this method.
*
* Excessive Width and Height values will cause a degridation in
* peformance depending upon platform.
*/
privatevoid initWarp(){
// Create Images...
logical =new BufferedImage(getWarpWidth(), getWarpHeight(), BufferedImage.TYPE_INT_RGB);
virtual =new BufferedImage(getWarpWidth(), getWarpHeight(), BufferedImage.TYPE_INT_RGB);
gLogical = logical.createGraphics();
gVirtual = logical.createGraphics();
mFrame =new BufferedImage(getWarpWidth(), getWarpHeight(), BufferedImage.TYPE_INT_RGB);
mFrameGraphics = mFrame.createGraphics();
// Hint at a faster render...
RenderingHints qualityHints =
new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
gVirtual.setRenderingHints(qualityHints);
gLogical.setRenderingHints(qualityHints);
mFrameGraphics.setRenderingHints(qualityHints);
gVirtual.setBackground(Color.black);
gVirtual.clearRect(0, 0, getWidth(), getHeight());
// Copy the orginal image to the logical area (ready for doFrame)
// Scaled to fit, aspect of orginal image will be a nonsense. Final frame will probably
// end up being copied to where orginal image came from anyway!
gLogical.setBackground(Color.black);
gLogical.clearRect(0, 0, getWarpWidth(), getWarpHeight());
if (getOriginalImage() !=null){
gLogical.drawImage(getOriginalImage(), 0, 0, logical.getWidth(), logical.getHeight(),this);
}
// Reset velocity
setVelocity(0);
// Need a rotational transformation...
xform =new AffineTransform();
xform.rotate(-2, (double) (getWarpWidth() >> 1), (double) (getWarpHeight() >> 1));
// Set-up the blur filter matrix...
//float weight = 1.0f/9.0f;
float weight = 0.114f;
float[] elements =newfloat[9];// create 2D array
// fill the array with nine equal elements
for (int i = 0; i < 9; i++){
elements = weight;
}
// use the array of elements as argument to create a Kernel
myKernel =new Kernel(3, 3, elements);
simpleBlur =new ConvolveOp(myKernel);
}
/**
* Use this method to get a warp animation frame.
* Velocity is increased automatically, however it can be overriden
* using setAccel before calling this method.
*/
publicvoid doFrame(){
int acs = getVelocity() >> 4;
int lw = getWarpWidth();
int lh = getWarpHeight();
if (acs < 64){
setVelocity(getVelocity() + getVelocityInc());
}
// Draw some colour randomisations in the centre...
for (int i = 0; i < getLightDensity(); i++){
int cr = mRnd.nextInt(255);
gLogical.setColor(rCol[cr]);
int x = mRnd.nextInt(8) - 4;
int y = mRnd.nextInt(8) - 4;
gLogical.drawLine((lw >> 1) + x - 1, (lh >> 1) + y - 1, (lw >> 1) + (x << 1) + 1, (lh >> 1) + (y << 1) + 1);
}
gLogical.setColor(Color.black);
gLogical.fillOval((lw >> 1) - 4, (lh >> 1) - 4, 8, 8);
// Blur the current logical to the virtual BufferedImage
simpleBlur.filter(logical.getData(), virtual.getRaster());// blur the image
// Copy the new blur back with interest (zoom & rotate).
gLogical.drawImage(virtual, - (acs << 1), -acs, lw + (acs << 2), lh + (acs << 1),this);// zoom
// Frame is ready, so lets paint now...
mFrameGraphics.drawImage(logical, 0, 0,this);// Copy to physical
}
}
Sorry, I posted those errors in the other thread when I was sleepy. There are, however, two errors specific to this class. They are on
rCol =new Color(255, i >> 3, i);
and
elments = weight;
Both rCol and elements are arrays, so I'm assuming that if I just add <i> afterward it will do as you intended..
> Ok, since none of the public methods returns an Image, I will just chill until you can find a code sample I think :D What you're doing in this class is interesting, that's why I'm ... well, interested in it.
Here you go...
(apologies for the long post Abuse).
Incidentally, the applet just does a "yield()" in the thread. This does not relinquish much back to the os. Suggest you use a sleep() and time it to 25th of a second sleep(40) - You'll get a smoother animation.
The Applet to test the Warp Class...
/*
* J2DWarpTest.java
*
* Created on 12 July 2001, 21:10
*/
package com.andand.parsec.applet;
import java.awt.*;
import java.awt.image.*;
import java.util.Random;
import java.awt.geom.AffineTransform;
import com.andand.parsec.gfx.Warp;
/**
*
* @author gisbya
* @version
*/
public class WarpApplet extends java.applet.Applet implements Runnable{
private boolean firstTime=true;
private Random mRnd = new Random(0);
private boolean keepgoing = true;
private boolean newframe = false;
private Thread mainex = null;
private Warp warpfactory = new Warp();
/** Initializes the applet J2DWarpTest */
public void init () {
if(firstTime){
warpfactory.setWarpBounds(200,100);
firstTime = false;
}
initComponents ();
}
/** This method is called from within the init() method to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the FormEditor.
*/
private void initComponents() {
setLayout(null);
setBackground(java.awt.Color.black);
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
formMousePressed(evt);
}
}
);
}
private void formMousePressed(java.awt.event.MouseEvent evt) {
keepgoing = false;// Cause termination
}
public void update(Graphics g)
{
paint(g);
}
public void paint(Graphics g)
{
if (getSize().width <= 0 || getSize().height <= 0)
return;
// When we draw, scale to current window size...
if (isShowing()) {
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(warpfactory.getFrame(),0,0,this.getWidth(), this.getHeight(),this);
if (newframe=false);
}
}
/**
* Main display Timer.. Fires every 25th of a second (50 fps)
**/
public void start() {
if (mainex == null) {
mainex = new Thread(this, "mainex");
mainex.start();
}
}
public void run() {
// Create an Image to act as copy of logical...
longtimex = 0;
while (keepgoing){
warpfactory.doFrame();
while (newframe) mainex.yield();// Last one done?
newframe=true;
repaint();
}
this.destroy();// Bye bye
}
// Variables declaration - do not modify
// End of variables declaration
}
The Warp class again...
/*
* warp.java
*/
package com.andand.parsec.gfx;
import java.awt.*;
import java.awt.Component.*;
import java.awt.image.*;
import java.util.Random;
import java.awt.geom.AffineTransform;
/**
*
* @author gisbya
* @version
*/
public class Warp extends java.awt.Component {
/*
* PROPERTIES ETC
*/
privateBufferedImagelogical;// Work image
privateBufferedImagevirtual;// Work image
private Graphics2D gLogical;
private Graphics2D gVirtual;
private Random mRnd = new Random(0);
private boolean keepgoing = true;
private boolean newframe = false;
private Color[]rCol = new Color[255];
// Rotation transformation...
private AffineTransform xform;
// Blur filter...
private Kernel myKernel;
private ConvolveOp simpleBlur;
// Property: BlurOn - Cause Warp effect to use blur filter (major processing!).
private booleanmBlurOn = true;
public boolean isBlurOn(){
return mBlurOn;
}
public voidtoggleBlurOn(){
if(!mBlurOn){
mBlurOn=true;
} else {
mBlurOn=false;
}
}
// Property: Reset - Cause Warp effect to reset itself.
private booleanmReset = false; // If true, reset warp effect.
public boolean resetPending(){
return mReset;
}
public voidsetReset(boolean r){
mReset=r;
// If reset requested, initialise...
if (mReset) {
initWarp();
mReset=false;// all done
}
}
public voidreset(){
setReset(true);
}
// Property: Original Image (Basis for warp to start (blur, zoom , etc).
private BufferedImagemOriginalImage;
public void setOriginalImage(BufferedImage g){
mOriginalImage=g;
}
public BufferedImage getOriginalImage(){
return mOriginalImage;
}
// Property: Current Frame
private BufferedImagemFrame;
public BufferedImage getFrame(){
return mFrame;
}
// Graphics2D context for mFrame
private Graphics2DmFrameGraphics;
public Graphics2D getFrameGraphics(){
return mFrameGraphics;
}
// Property: Warp effect work area size width
private int mWidth = 200;
public void setWarpWidth(int w){
mWidth=w;
// Width has changed, so cause a reset...
this.reset();
}
public int getWarpWidth(){
return mWidth;
}
// Property: Warp effect work area size height
private int mHeight = 100;
public void setWarpHeight(int h){
mHeight=h;
// Width has changed, so cause a reset...
this.reset();
}
public int getWarpHeight(){
return mHeight;
}
// Property: Warp effect velocity
private int mVelocity = 0;
public void setVelocity(int a){
mVelocity=a;
}
public int getVelocity(){
return mVelocity;
}
// Property: Warp effect velocity increment
private int mVelocityInc = 1;
public void setVelocityInc(int a){
mVelocityInc=a;
}
public int getVelocityInc(){
return mVelocityInc;
}
// Property: Light randomisation effect
private int mLightDensity = 16;
public void setLightDensity(int a){
mLightDensity=a;
}
public int getLightDensity(){
return mLightDensity;
}
// Set width and height at the same time...
public void setWarpBounds(int width, int height){
mWidth=width;
mHeight=height;
this.reset();
}
/** Creates new warp */
public Warp() {
super();
// Set up an Array of colors...
for (int i=0;i<255;i++)
{
//rCol[i] = new Color(i>>3, i, 255);
rCol[i] = new Color(255,i>>3, i);
}
// Initialise...
initWarp();
}
/*
* INTERNAL METHODS (To this bean)
*/
/**
* Used to initialise a "warp" effect. Recreates all off-screen
* images and maps OriginalImage on to the first frame.
*
* Make sure OriginalImage, Width and Height are set to desired
* values before using this method.
*
* Excessive Width and Height values will cause a degridation in
* peformance depending upon platform.
*/
private voidinitWarp(){
// Create Images...
logical = new BufferedImage(getWarpWidth(), getWarpHeight(), BufferedImage.TYPE_INT_RGB);
virtual = new BufferedImage(getWarpWidth(), getWarpHeight(), BufferedImage.TYPE_INT_RGB);
gLogical = logical.createGraphics();
gVirtual = logical.createGraphics();
mFrame = new BufferedImage(getWarpWidth(), getWarpHeight(), BufferedImage.TYPE_INT_RGB);
mFrameGraphics = mFrame.createGraphics();
// Hint at a faster render...
RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
qualityHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_SPEED);
gVirtual.setRenderingHints(qualityHints);
gLogical.setRenderingHints(qualityHints);
mFrameGraphics.setRenderingHints(qualityHints);
gVirtual.setBackground(Color.black);
gVirtual.clearRect(0,0,getWidth(),getHeight());
// Copy the orginal image to the logical area (ready for doFrame)
// Scaled to fit, aspect of orginal image will be a nonsense. Final frame will probably
// end up being copied to where orginal image came from anyway!
gLogical.setBackground(Color.black);
gLogical.clearRect(0,0,getWarpWidth(),getWarpHeight());
if (getOriginalImage() != null){
gLogical.drawImage(getOriginalImage(),0,0,logical.getWidth(),logical.getHeight(),this);
}
// Reset velocity
setVelocity(0);
// Need a rotational transformation...
xform = new AffineTransform();
xform.rotate(-2,(double)(getWarpWidth()>>1), (double)(getWarpHeight()>>1));
// Set-up the blur filter matrix...
//float weight = 1.0f/9.0f;
float weight = 0.114f;
float[] elements = new float[9]; // create 2D array
// fill the array with nine equal elements
for (int i = 0; i < 9; i++) {
elements[i] = weight;
}
// use the array of elements as argument to create a Kernel
myKernel = new Kernel(3, 3, elements);
simpleBlur = new ConvolveOp(myKernel);
}
/**
* Use this method to get a warp animation frame.
* Velocity is increased automatically, however it can be overriden
* using setAccel before calling this method.
*/
public voiddoFrame(){
int acs = getVelocity()>>4;
int lw = getWarpWidth();
int lh = getWarpHeight();
if (acs < 64) {
setVelocity(getVelocity()+getVelocityInc());
}
// Draw some colour randomisations in the centre...
for (int i=0; i<getLightDensity();i++){
int cr=mRnd.nextInt(255);
gLogical.setColor(rCol[cr]);
int x=mRnd.nextInt(8)-4;
int y=mRnd.nextInt(8)-4;
gLogical.drawLine((lw>>1)+x-1,(lh>>1)+y-1,(lw>>1)+(x<<1)+1,(lh>>1)+(y<<1)+1 );
}
gLogical.setColor(Color.black);
gLogical.fillOval((lw>>1)-4,(lh>>1)-4,8,8);
// Blur the current logical to the virtual BufferedImage
simpleBlur.filter(logical.getData(), virtual.getRaster()); // blur the image
//simpleBlur.filter(logical, virtual); // blur the image
//gVirtual.drawImage(logical,0,0,this);
// Copy the new blur back with interest (zoom & rotate).
//gLogical.drawImage(virtual,0,0,this));// copy back
//gVirtual.drawImage(logical,xform,this);// Rotate
//gLogical.drawImage(virtual,-acs,-acs,lw+(acs<<1),lh+(acs<<1), this); // zoom
gLogical.drawImage(virtual,-(acs<<1),-acs,lw+(acs<<2),lh+(acs<<1), this); // zoom
// Frame is ready, so lets paint now...
mFrameGraphics.drawImage(logical,0,0,this);// Copy to physical
}
}