www.xbdev.net xbdev - software development
Monday December 10, 2018
home | about | contact | Donations

     
 

Slice of Java.

Its simple and its powerful...

 

 

 

Day '1' plotting that pixel!

by Ben Kenwright


We'll start simple, really simple!  Code doesn't necessarily have to be complex to create amazing effects - and even today, with P4's and super powerful graphics cards, even the sloppiest and most inefficient code can run fast.  WHAT is important though, is that your code works and that it does what its suppose to.  As we can start of by creating simple but effective drawing routines....then if we need to we can just rewrite those routines without effecting our code :)

 

You may ask at this early stage, why where messing around with pixels, and java 1.1 and not jumping in at the deep end with Java3D and the Java VM 1.4 or later.  Well by teaching you the basics of 3D...and I mean the underlying basics...how to actually create 3D from nothing more than pixels and maths...you'll be able to take those Java3D library's and do much more with them, as you know what is really happening.

I also dislike visiting web pages, where it constantly asks you to add a new plug-in or on some occasions just shows a grey box where the applet should be :-/  Nearly all browsers support java 1.1, and even windows xp default is with java 1.1 enabled.  So you won't have to worry about people coming to you and saying that your cool demo you created isn't working :)

 

 

By accessing the pixels directly we can do so much more:

  • Create dynamic images and patterns on the fly instead of loading images from file
  • Dynamic images can contain a lot more details
  • Create our own 3D render ware and not have to rely on other API's

 

So lets create a very simple applet:

 

import java.applet.*;

public class setpixels extends Applet

{

}// End of our Applet

 

And we compile it like this:

 

C:>javac -target 1.1 setpixels.java

 

Don't forget that we must name the file the same name as the entry class....so for example if we'd called our applet "aba" we'd have to name our file "aba.java".  Else you'll get a compile error.

 

Now you compile this above...wooosh...it compiles no errors...nothing...but it creates a "setpixels.class" file, which is what the browser uses.

There is two main ways to run the applet - the most common way is through your browser alternatively you can use the java binary called 'appletviewer.exe' which you call and pass the name of the name of the html file.

 

You need a html file to show off your applet, and this is all a html file has to contain:

 

<html>

<head>

<title>xbdev applet demo</title>

</head>

<body>

 

<applet code="setpixels.class" width="320" height="320">

</applet>

 

</body>

</html>

 

 

A warning to the new here - if you use your browser to view your applet changes, you'll find that you have to close all your browser windows and I mean all...and re-open the applet in the browser again.  As your browser caches the '.class' file.  That's why I always find it better to test the applets out in the 'appletviewer.exe' program...just call it like this at the command prompt:

 

C:>appletviewer.exe setpixels.html

 

Of course you can name your html file anything you want!  And make sure your in the same directory as your .html and .class file.

 

*Drinks some coffee*...hehe...well when you start out in java, all this seems pretty straight forwards...but don't worry...thats about it, we can start getting down to some code now.  You run the above applet and guess what happens?  You get a grey applet box in your browser about 320x320 in size :)

 

import java.awt.*;                                 // We need this so we can use 'Graphics' class

import java.applet.*;                             // So we can make an applet :)

public class setpixels extends Applet

{

        public void init(){}                         // Called when the applet is about to start

        public void start(){}                      // When the applet starts or gains focus again

        public void stop(){}                      // When the applet window looses focus

        public void destroy(){}                 // Called when applet dies and is gone forever

        public void update(){}                  // When its time to repaint - if we don't override this

                                                              // this function it clears the screen for us

        public void paint(Graphics g) {}    // The function that does the painting

}// End of our Applet

 

 

Well what we have here, is what all applets have!  I've put a small description of what each one basically does....I usually find that you only use init() and paint() on most occassions....but then you also find you need to do an update() on as well or you get this flicker due to it always clearing your screen.

 

Main ways to set a pixel are:

 

drawLine (x,y,x,y)

fillRect (x,y,1,1)

MemoryImageSource(..) which is inherited from ImageProducer

 

Speed is the biggest factor here!  Depending on how many pixels you want t plot is one factor...as if your going to do a complete screen render of your own pixels, it faster to have direct access to the image pixels through 'MemoryImageSource(..)' but then to plot a few pixels on another image you might just use fillRect(..).

 

Method A - Plot Pixel

 

import java.awt.*;

import java.applet.*;

public class setpixels extends Applet

{

         int x=10, y=10;

         public void paint(Graphics g)

           {                         g.setColor( Color.red );

                                   g.fillRect( x, y, 1, 1 );

           }

}// End of our Applet

 

 

Method B - Plot Pixel

 

import java.awt.*;

import java.awt.image.*;                                                                       // Need for MemoryImageSource(..)

import java.applet.*;

public class setpixels extends Applet

{

             Image c;

             int pixels[] = new int[320 * 320];

             public void init ()

             {                           int n = 0;

                                          ImageProducer p;

                                          for (int i = 0; i < 320 ; i++)                           // Clears the screen to green

                                             for ( int j = 0; j < 320 ; j++)

                                                 pixels[n++]=0xff00ff00;

                                          pixels[30 + 35*320] = 0xff0000ff;              // Set pixel at x=30, y=35 to blue

                                          pixels[30 + 36*320] = 0xff0000ff;              // Set pixel at x=30, y=36 to blue

                                          pixels[30 + 37*320] = 0xff0000ff;              // Set pixel at x=30, y=37 to blue

                                          p = new MemoryImageSource(320,320,pixels,0,320);

                                          c = createImage(p);

             }

             public void paint(Graphics g)

             {                           g.drawImage(c,0,0,this);

             }

}// End of our Applet

 

 

 

Method C - Dynamic method B

 

import java.awt.*;

import java.awt.image.*;                                                                    // Need for MemoryImageSource(..)

import java.applet.*;

public class setpixels extends Applet

{

              Image c;

                   MemoryImageSource p;

              int pixels[] = new int[320 * 320];

              public void init ()

              {                     int n = 0;

                                     for (int i = 0; i < 320 ; i++)                           // Clears the screen to green

                                         for ( int j = 0; j < 320 ; j++)

                                              pixels[n++]=0xff00ff00;

                                     p = new MemoryImageSource(320,320,pixels,0,320);

                                     p.setAnimated(true);

                                     p.setFullBufferUpdates(true);

                                     c = createImage(p);

              }

              public void paint(Graphics g)

              {                    pixels[30 + 35*320] = 0xff0000ff;                       // Set pixel at x=30, y=35 to blue

                                    pixels[30 + 36*320] = 0xff0000ff;                       // Set pixel at x=30, y=36 to blue

                                    pixels[30 + 37*320] = 0xff0000ff;                       // Set pixel at x=30, y=37 to blue

                                    p.newPixels(0,0,/*width*/320,/*height*/320);    // Update the images pixels

                                    g.drawImage(c,0,0,this);

              }

              public void update(Graphics g){}                                             // So it doesn't flicker white/green

}// End of our Applet

 

 

Method C is possibly the most preferred way, but then again I've seen people who write there own class inherited from 'ImageProducer' because the 'MemoryImageSource' class is inherited from it...so there is nothing stopping us from inheriting and doing our own.

Might want to look at Method C, and instead of calling p.newPixels(..) you could use p.flush().  And then if you think further, possibly use 'ImageProducer' instead of 'MemoryImageSource'...like this:

 

import java.awt.*;

import java.awt.image.*;                                                                       // Need for MemoryImageSource(..)

import java.applet.*;

public class setpixels extends Applet

{

             Image c;

             int pixels[] = new int[320 * 320];

             public void init ()

             {              int n = 0;

                            ImageProducer p;

                            for (int i = 0; i < 320 ; i++)                                      // Clears the screen to green

                            for ( int j = 0; j < 320 ; j++)

                            pixels[n++]=0xff00ff00;

                            p = new MemoryImageSource(320,320,pixels,0,320);

                            c = createImage(p);

             }

             public void paint(Graphics g)

             {             pixels[30 + 35*320] = 0xff0000ff;                           // Set pixel at x=30, y=35 to blue

                           c.flush();

                           g.drawImage(c,0,0,this);

             }

             public void update(Graphics g){} // So it doesn't flicker white/green

}// End of our Applet

 

 

It looks hard!  Yup, having to learn all those new API's...but the beauty of them is that they've been around since the beginning of java and are still around with java 1.4 which means we can create applets that will work even on my best friend 'kl0wn' pentium-2 350 Mhz pc...which is running windows 98 and java 1.1 :)

 

Lets add a small function to catch mouse input so we can in effect draw lots of pixels on the screen

 

 

import java.awt.*;

import java.applet.*;

public class setpixels extends Applet

{

                Image c;

                public void init ()

                {                 c = createImage(320,320);

                }

                public void paint(Graphics g)

                {                 g.drawImage(c,0,0,this);

                }

                public void update(Graphics g){ paint(g); }                                               // Is called when we call repaint()

                public void setPixel(Image image, int x, int y, Color color )

                {

                                Graphics g = c.getGraphics( );

                                g.setColor( color );

                                g.fillRect( x, y, 1, 1 );

                                g.dispose( );

                }// End of setPixel(..)

 

/*********************************************************************************************/

/*                                                                                                                                                                                      */

/*                 Capture mouse drags                                                                                                                                  */

/*                 Parameters:                                                                                                                                                 */

/*                 evt is The event...                                                                                                                                        */

/*                 x is the x mouse position                                                                                                                              */

/*                 y is the y mouse position                                                                                                                              */

/*                 return whether or not we handled the event                                                                                                */

/*                                                                                                                                                                                      */

/*********************************************************************************************/

                public boolean mouseMove(Event evt, int x, int y)

                {              setPixel(c, x, y, Color.red );

                                repaint();

                                return true;

                }// End of mouseDrag(..)

}// End of our Applet

 

All we've done in the above applet, is take our 'fillRect' and create a function that we can call to draw pixels :)  Then I've tapped into the applet mouseMove function to capture mouse events...and plot the pixels on the screen.  Simple but effective.

 

This is one of those cool applets that you put on your web page so you can make pretty patterns...lol.... if you move the mouse really really slowly when you run the code, you'll be able to make some notes :)

 

Well have the power of the PIXEL now!  Today applet doodle 101...tomorrow...LINES...then onto 3D WORLDS :-D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.