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..

[16172 byte] By [markuskidda] at [2007-9-28 2:11:27]
# 1

You said in another post:

>To get an image from Warp Effect, repeated calls as follows...

>getWarpEffect().doFrame();

Well, doFrame() does not return an image. What exactly does this class do and how are you supposed to use it?

Here is an example of what I assumed would work (since you extend JComponent):

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

class WarpEffects extends JFrame {

public WarpEffects() {

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

dispose();

System.exit(0);

}

});

warp = new Warp();

getContentPane().add(warp);

}

public void paint(Graphics g) {

warp.doFrame();

super.paint(g);

}

Warp warp;

public static void main(String args[]) {

System.out.println("Starting WarpEffects...");

WarpEffects mainFrame = new WarpEffects();

mainFrame.setSize(400, 400);

mainFrame.setTitle("WarpEffects");

mainFrame.setVisible(true);

}

}

But... this does not seem to do anything...

markuskidda at 2007-7-7 21:44:03 > top of Java-index,Other Topics,Java Game Development...
# 2

Opps...

Good point, I hadn't looked at this code for ages - Just copied it straight out of my libraries.

Basically, there is another attribute mFrame that holds an Image where the effect will be finally rendered.

Also, don't add as a component to the JFrame, just instantiate the class. I can't for the life of remember why I made it a component.

Apologies for the nonsence (I knew it was a mistake to post the flippin' thing in that game thread - thought it might have been useful.. d'oh!).

When I get a chance this week, I'll hunt around for the test code I used to test the class. If I find it, I'll post it up.

Rather embarrasing when you can't remember how it works / should be used. :o)

If you can fathom it before my search, the final image is delivered (drawImage) in the the property mMainFrame (graphic context).

You'll need a repeating loop (implement Runnable) that calls doFrame(), then does something like...

public void run () {

int frametodo = 100;// renders.

while (framestodo > 0) {

framestodo -= 1;

warp.doFrame();

repaint()

try {

sleep(40); // 1 25th of a second

} catch (Exception e) {

}

}

}

paint(Graphics g) {

...

g.drawImage(warp.getFrame(),0,0,warp.getWarpWidth(),warp.getWarpHeight(),this);

...

}

gisbyaa at 2007-7-7 21:44:03 > top of Java-index,Other Topics,Java Game Development...
# 3
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.
markuskidda at 2007-7-7 21:44:03 > top of Java-index,Other Topics,Java Game Development...
# 4
No problem... Please be patient. Been working very late just lately. getFrame() is the one that returns the rendered Image (BufferedImage).
gisbyaa at 2007-7-7 21:44:03 > top of Java-index,Other Topics,Java Game Development...
# 5

> 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

}

}

gisbyaa at 2007-7-7 21:44:03 > top of Java-index,Other Topics,Java Game Development...