Skip to main content
gamedev.net
🔒 Locked

[java] Images in Java

Started by Mary Coory 22 replies 5.4k views
Original Post
Mary Coory
Mary Coory
Good Day Dear ALL, I'm a very newbie in using Java, but I did good in coding my project till I stuck with images I have the following code: int rawHeight = 256; int rawWidth = 256; int [][] MyPixels = new int[rawWidth][rawHeight]; for(int i = 0; i < (rawWidth);i++){ for(int j = 0; j < (rawHeight);j++) { MyPixels[j] = MyPixels[j] + (i*j) + 100; } } How to represent "MyPixels" array as an image ; assume that the content of each MyPixel[j] is a color of type integer??
sushi-one
sushi-one
You just need to create an image of your pixel array using "createImage" and "MemoryImageSource" :) :

    public Image generateImage() {        int rawHeight = 256;        int rawWidth = 256;        int[] myPixels = new int[rawWidth * rawHeight];        for (int y = 0; y < rawHeight; y++) {            for (int x = 0; x < rawWidth; x++) {                myPixels[y * rawWidth + x] = ((y ^ x) << 24) | ((y ^ x) << 16) | ((y ^ x) << 8);            }        }        return (this.createImage(new MemoryImageSource(rawWidth, rawHeight, myPixels, 0, rawWidth)));    }


merry x-mas btw!:)
Hans-Petter Harveg
Mary Coory
Mary Coory
Thank you very much sushi-one :)

i tried your method and it works,

but I have some questions :

I stored my values ( pixels) in int[] myPixels and I already have values there, for example myPixels[11] = 125,
what is the purpose of ((y ^ x) << 24) | ((y ^ x) << 16) | ((y ^ x) << 8); ?

and what are 24,16,8 ??




SamLowry
SamLowry
Not sure if you know this, so I'll explain anyway:

A color can be decomposed in 3 components: Red, Green and Blue. All colors we see can be described as "that much of Red, that much of Green and that much of Blue". The amount of each color you take is represented as a byte (range 0-255), so if you want black, you take 0 Red, 0 Green, 0 Blue. If you want pure red, 255 Red, 0 Green, 0 Blue. If you want to mix Red and Green (which would give yellow I think) you would take 255 Red, 255 Green and 0 Blue. Light Gray would be 192 R, 192 G, 192 B, etc.

There's also a 4th component, the alpha channel, which is used for other purposes, and should be 255 for now.

These 4 components can be encoded in a integer as follows:
int colorValue = (255 << 24) | (r << 16) | (g << 8) | b;

(What happens here is that you divide the integer in 4 bytes, each byte representing one component. The << operator moves the values around in the integer. So what that line of code means is "take value 255, and move it 3 bytes (=24 bits) to the left, then take the red component, move it 2 bytes to the left, so that it's next the the 255, etc.")


About that ((y ^ x) << 24) | ((y ^ x) << 16) | ((y ^ x) << 8), it fills the image with gray pixels (light gray, dark gray, ... randomly over the image). I don't think that's what you want.

Since you have a 2D array, and the MemoryImageSource wants a 1D array, I would suggest that you modify your code so that you immediately work with a 1D array.

int rawHeight = 256;int rawWidth = 256;int[] MyPixels = new int[rawWidth * rawHeight];for(int i = 0; i < rawWidth; i++){  for(int j = 0; j < rawHeight; j++) {    MyPixels[j * rawWidth + i] = MyPixels[j * rawWidth + i] + (i*j) + 100;  }}


Haven't tested it, but it should work. It can also be optimised a bit, but I'll leave your code like that, so that it's more easily recognizable.
Mary Coory
Mary Coory
Thank you very much SamLowry;

Your explanation made the picture much more clear.

Still one point left, what about if I want to save the image?
SamLowry
SamLowry
Saving can be done in a lot of ways. I'll make the assumption that you just want to write your image to a known format so that other people can easily access it.

I've just tested this approach, it seems to work:
construct a BufferedImage instance, fill in the pixel data and use ImageIO to save it to a file.

int[] pixelData; // contains your pixels in a 1D arrayint width, height; // I assume these variables contain the image's width & height/* Create the buffered image instance */BufferedImage image =    new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);/* Set color data */image.setRGB(0, 0, width, height, pixelData, 0, width);/* Save it to file */try{    ImageIO.write( image, "PNG", new File("output.png") );}catch ( IOException e ){    // Something bad happened    System.out.println(e);}


I've tried other formats, only JPG seems to work (but produces the wrong colors...).
Mary Coory
Mary Coory
Thanks alot SamLowry, I used your method and it works :)
but instead of save it in using PNG format I used JPG format, but I get a black image !!

int rawHeight = 256;
int rawWidth = 256;
int[] myPixels = new int[rawWidth * rawHeight];
for(int i = 0; i < rawWidth; i++){
for(int j = 0; j < rawHeight; j++) {
MyPixels[j * rawWidth + i] = myPixels[j * rawWidth + i] + (i*j) + 100;
}
}
/* Create the buffered image instance */
BufferedImage image =
new BufferedImage(rawWidth, rawHeight, BufferedImage.TYPE_INT_ARGB);

/* Set color data */
image.setRGB(0, 0, rawWidth, rawHeight, myPixels, 0, rawWidth);

/* Save it to file */
try
{
ImageIO.write( image, "JPG", new File("output.JPG") );
}
catch ( IOException e )
{
// Something bad happened
System.out.println(e);
}


Then I tried to show the image in the screen using :
ImageIcon image1= newImageIcon("output.jpg");
JLabel label = new JLabel();
label.setIcon(image1);
add(lable);

the result was what screen with out any image ?????
SamLowry
SamLowry
I had the same problem when testing; the JPEG could only be read by PhotoShop, and even then the colors were all wrong.

I really can't give you a constructive answer. My normal answer would be "it's just typical Java, I have learnt not to expect anything from it. Instead of being angry when it doesn't work, I'm happy when it does work."

There are surely other ways (that work). I hope someone else on this forum can help you.

Found something that might help you:
Docs
Example usage

[Edited by - SamLowry on December 26, 2004 4:57:47 PM]
Mary Coory
Mary Coory

Hi again SamLowry,

Thanks for your wonderful support :).

I found this program that could show the image without saving it, I tried it and it was fine.

The problem now that I want to make this program as a class in "my program" then I want to know how I let it accept myPixels[] in order to view the image?


import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

class Image05 extends Frame{
Image rawImage;
int rawWidth;
int rawHeight;

//Inset values for the container object
int inTop;
int inLeft;

//=====================================================//

public static void main(String[] args){
Image05 obj = new Image05();//instantiate this object
obj.repaint();//render the image
}//end main
public Image05(){//constructor

rawImage = generateImage(); /// ????
//Toolkit.getDefaultToolkit().getImage("junk.gif");

MediaTracker tracker = new MediaTracker(this);
tracker.addImage(rawImage,1);

try{ //because waitForID throws InterruptedException
if(!tracker.waitForID(1,10000)){
System.out.println("Load error.");
System.exit(1);
}//end if
}catch(InterruptedException e){System.out.println(e);}

//Raw image has been loaded. Establish width and
// height of the raw image.
rawWidth = rawImage.getWidth(this);
rawHeight = rawImage.getHeight(this);

this.setVisible(true);//make the Frame visible

//Get and store inset data for the Frame object so
// that it can be easily avoided.
inTop = this.getInsets().top;
inLeft = this.getInsets().left;

this.setSize(inLeft+rawWidth,inTop+2*rawHeight);
this.setTitle("Copyright 1997, Baldwin");
this.setBackground(Color.yellow);

//Declare an array object to receive the pixel
// representation of the image
int[] pix = new int[rawWidth * rawHeight];

//Convert the rawImage to numeric pixel representation
try{//because grapPixels() throws InterruptedException
//Instantiate a PixelGrabber object specifying
// pix as the array in which to put the numeric
// pixel data. See JDK 1.1.3 docs for parameters
PixelGrabber pgObj = new PixelGrabber(
rawImage,0,0,rawWidth,rawHeight,
pix,0,rawWidth);

//Invoke the grabPixels() method on the PixelGrabber
// object to actually convert the image to an array
// of numeric pixel data stored in pix. Also test
// for success in the process.
if(pgObj.grabPixels() && ((pgObj.getStatus() &
ImageObserver.ALLBITS) != 0)){
//Mask the red byte out of every pixel by ANDing
// the red byte with 00. Also make partially
// transparent by ANDing the alpha byte with C0
for(int cnt = 0; cnt < (rawWidth*rawHeight);cnt++){
pix[cnt] = pix[cnt] & 0xC000FFFF;
}//end for loop
}//end if statement
else System.out.println("Pixel grab not successful");
}catch(InterruptedException e){System.out.println(e);}


//Anonymous inner-class listener to terminate program
this.addWindowListener(
new WindowAdapter(){//anonymous class definition
public void windowClosing(WindowEvent e){
System.exit(0);//terminate the program
}//end windowClosing()
}//end WindowAdapter
);//end addWindowListener
}//end constructor
//=======================================================//

//Override the paint method to display both the rawImage
// and the modImage on the same Frame object.
public void paint(Graphics g){

g.drawImage(rawImage,inLeft,inTop,this);


}//end paint()
}//end Image05 class
//=======================================================//


And in my main program I have the method:
//=====================================================//

public Image generateImage() {

int rawHeight = 256;
int rawWidth = 256;
//int[] myPixels = new int[rawWidth * rawHeight];

int Height = 2048;
int[] myPixels = new int[rawWidth * rawHeight];
for (int i = 0; i < Height; i++)
{
myPixels = i*100;
}

for (int y = 0; y < rawHeight; y++) {
for (int x = 0; x < rawWidth; x++) {
myPixels[y * rawWidth + x] = (myPixels[y * rawWidth + x] << 24) | (myPixels[y * rawWidth + x] << 16) | (myPixels[y * rawWidth + x] << 8);
}
}
return (this.createImage(new MemoryImageSource(rawWidth, rawHeight, myPixels, 0, rawWidth)));
//return (this.createImage(new MemoryImageSource(Height, Height, myPixels, 0, Height)));
}

which generate the image. How can I connect the two programs together so I can view the image.

Thanks

SamLowry
SamLowry
If you just want to draw your image to the screen, there's no need to save it first. Here are three classes that may help you:

import java.awt.image.*;public class App{    public static void main(String[] args)    {        // Produce image        BufferedImage image =            new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);                for ( int y = 0; y != image.getHeight(); ++y )        {            for ( int x = 0; x != image.getWidth(); ++x )            {                int t = (x & 0xFF);                int u = (y & 0xFF);                               int c = (255 << 24) | (t << 16) | (u << 8) | t;                               image.setRGB(x, y, c);            }        }                // Create new window that will draw the image to the screen        ImageWindow wnd = new ImageWindow(image);                wnd.setVisible(true);    }}



import java.awt.*;import javax.swing.*;public class ImageViewer extends JComponent{    public ImageViewer()    {            }        protected void paintComponent(Graphics g)    {        System.out.println("Painting");        if ( _image != null )        {            g.drawImage(_image, 0, 0, new DummyObserver());        }    }        public void setImage(Image image)    {        _image = image;        repaint();    }        private Image _image;            private static class DummyObserver implements ImageObserver    {        public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)        {            return true;        }    }}


import java.awt.*;import javax.swing.*;public class ImageWindow extends JFrame{    public ImageWindow(Image image)    {        super("Image viewer");                _imageViewer = new ImageViewer();        getContentPane().add( _imageViewer );                _imageViewer.setImage(image);        setSize(300, 300);        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );    }        private ImageViewer _imageViewer;}


The ImageWindow and ImageViewer classes are a bit primitive, but they work here :)
Mary Coory
Mary Coory
I really appreciate your efforts with me SamLowry. I'll try the code now but I was wonder what about myPixels array ? . I didn't know where to put in your new code and it contains values that I have to view as an Image ?. Or, instead of using my myPixels array I can use R[] G[] B[] arrays which contain integer values to be represented as an image. Is it OK to exchange :

for ( int y = 0; y != image.getHeight(); ++y )
{
for ( int x = 0; x != image.getWidth(); ++x )
{
int t = (R[x] & 0xFF) // t = (x & 0xFF);
int u = (G[x] & 0xFF) //(y & 0xFF);
// what about B[] ???

int c = (255 << 24) | (t << 16) | (u << 8) | t;

image.setRGB(x, y, c);
}
}

Thanks million
SamLowry
SamLowry
Updated version for the App class:
import java.awt.image.*;public class App{    public static void main(String[] args)    {        BufferedImage image = paintImage();                ImageWindow wnd = new ImageWindow(image);        wnd.setVisible(true);    }        public static BufferedImage paintImage()    {        BufferedImage image =            new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);                int[] pixels = new int[256*256];                // Fill array with color values        for ( int x = 0; x != 256; ++x )        {            for ( int y = 0; y != 256; ++y )            {                pixels[256*y+x] = (0xFF << 24) | (x * y + 100);            }        }                // Write colors to image        image.setRGB(0, 0, 256, 256, pixels, 0, 256);                return image;    }    // r,g,b should be >= 0 and <= 255, otherwise    // you will get strange results    private static int makeRGB(int r, int g, int b)    {        return (0xFF << 24) | (r << 16) | (g << 8) | b;    }        // grayLevel should be >=0 and <255.    // 0 gives black, 255 white.    private static int makeGray(int grayLevel)    {        return makeRGB(grayLevel, grayLevel, grayLevel);    }}


All image producing code resides in the paintImage() method.
I have put the computations from your first post there.


A problem with your formula (MyPixels[j] = MyPixels[j] + (i*j) + 100;) is that it doesn't take into account the structure of color encoding (the ARGB thing); this might of course be exactly what you want:



However, if you would want to have a more "mathematical" view of the function x*y+100, you will have to take a different approach.

=== only read this if a math plot is what you need ===
Color space is three-dimensional (R, G, and B), each with range 0-255, and you want to plot a one dimensional value in it, whose range is in theory unlimited. So you will have to "pick a line" in color space onto which you map all function values.
So, for example, you can choose to work with gray levels: the lowest values are represented by black, the highest values by white, and all intermediary values by shades of gray. You can also work with hue (rainbow colors).
This gives you


So, if you're interested to have these kinds of plots, you can use this class:
import java.awt.Color;import java.awt.image.BufferedImage;import java.util.Arrays;public class ImageProducer{    public ImageProducer(int width, int height)    {        if ( width <= 0 || height <= 0 )        {            throw new IllegalArgumentException();        }                _width = width;        _height = height;        _buffer = new float[width][height];        _min = 0;        _max = 1;    }        public int getWidth()    {        return _width;    }        public int getHeight()    {        return _height;    }        /*     * Clears the image. Use this if you want     * to re-use an image producer for a new image.     */    public void clear()    {        for ( int i = 0; i != _width; ++i )        {            Arrays.fill( _buffer, 0 );        }                _min = 0;        _max = 1;            }        /*     * Sets a pixel at the specified position.     * Level does not represent a color, merely a value.     */    public void setPixel(int x, int y, float level)    {        _buffer[x][y] = level;                if ( level > _max )        {            _max = level;        }                if ( level < _min )        {            _min = level;        }    }        /*     * After you have set all pixels to their correct levels,     * this method scales all these values, and produces     * an image using shades of gray.     */    public BufferedImage produceGrayLevels()    {        normalizeBuffer();                BufferedImage image =            new BufferedImage(_width, _height, BufferedImage.TYPE_INT_ARGB);                for ( int x = 0; x != _width; ++x )        {            for ( int y = 0; y != _height; ++y )            {                int c = (int)(255*_buffer[x][y]);                image.setRGB(x, y, makeGray(c));            }        }                return image;    }        /*     * After you have set all pixels to their correct levels,     * this method scales all these values, and produces     * an image using rainbow colors.     */    public BufferedImage produceHueLevels()    {        normalizeBuffer();                BufferedImage image =            new BufferedImage(_width, _height, BufferedImage.TYPE_INT_ARGB);                for ( int x = 0; x != _width; ++x )        {            for ( int y = 0; y != _height; ++y )            {                float level = _buffer[x][y];                int c = Color.HSBtoRGB(level, 1, 1);                                image.setRGB(x, y, c);            }        }                return image;    }        private int makeGray(int level)    {        return (0xFF << 24) | (level << 16) | (level << 8) | level;    }        private void normalizeBuffer()    {        for ( int i = 0; i != _width; ++i )        {            for ( int j = 0; j != _height; ++j )            {                _buffer[j] += _min;                _buffer[j] /= (_max-_min);            }        }    }        private float[][] _buffer;        private float _min;        private float _max;        private int _width;        private int _height;    }


Example usage for your function x*y+100 (replaces the paintImage() method in the App class):

    public static BufferedImage paintImage()    {        ImageProducer producer = new ImageProducer(256, 256);                for ( int x = 0; x != producer.getWidth(); ++x )        {            for ( int y = 0; y != producer.getHeight(); ++y )            {                producer.setPixel(x, y, x * y + 100);            }        }                // Produces rainbow-colors view        return producer.produceHueLevels();    }


You will not have to write all pixel colors to an int[] array first, the producer will act as "array" for you to write your values in. But you can of course still work with an array if you wish, and copy all the integers in it one by one to the producer.
Mary Coory
Mary Coory

Wonderful :). Thank you very much SamLowry :). I start like Java :).
By the way, you said :"the producer will act as "array" for you to write your values in. But you can of course still work with an array if you wish, and copy all the integers in it one by one to the producer."

If I want to do that- I mean if I have - as I said before - three arrays-:

R = i/255*255;
G = R/255;
B = (R+ G)/255;

How does I let the producer generate an image using the three arrays:
I believe that I have to fill "_buffer " with values from R,G, & b, Correct me if I'm wrong ??

Thanks alot again SamLowry.
Mary Coory
Mary Coory

I tried to the following:
public static BufferedImage paintImage()
{
ImageProducer producer = new ImageProducer(256, 256);

for ( int x = 0; x != producer.getWidth(); ++x )
{
for ( int y = 0; y != producer.getHeight(); ++y )
{
int t = R[y * producer.getWidth()+ x];
int w = G[y * producer.getWidth()+ x];
int v = B[y * producer.getWidth()+ x];


producer.setPixel(t, w, v);
}
}

But it doesn't work. I don't know why?
Mary Coory
Mary Coory
OOps I did a mistake:

The correct version here :

public static BufferedImage paintImage()
{
ImageProducer producer = new ImageProducer(256, 256);

for ( int x = 0; x != producer.getWidth(); ++x )
{
for ( int y = 0; y != producer.getHeight(); ++y )
{
//int t = R[y * producer.getWidth()+ x];
//int w = G[y * producer.getWidth()+ x];
???? int v = B[y * producer.getWidth()+ x];


producer.setPixel(x, y, v);
}
}

I don't know how to set v so that it will take its value from R[],G[],B[] ???
SamLowry
SamLowry
If you're using three arrays, you can't use the ImageProducer.
An image is two dimensional, each pixel has coordinates (x,y). For each pixel, you can specify a color, which is 3D (r,g,b). So, you have a function (x,y) -> (r,g,b). The ImageProducer simplifies this by letting you only specify 1D values: (x,y) -> t. This t is automatically mapped to an (r,g,b). Hence (x, y) --you--> t --producer--> (r,g,b).

Using three arrays, you define (r,g,b)-values yourself, so you don't need the producer anymore.


Here's code that writes the values from R,G,B arrays to an image (assuming your R, G, B arrays contain r, g, b values respectively, and contain enough values for the entire image (width*height number of values):
import java.awt.image.*;public class App{    public static void main(String[] args)    {        BufferedImage image = paintImage();                ImageWindow wnd = new ImageWindow(image);        wnd.setVisible(true);    }        public static BufferedImage paintImage()    {        BufferedImage image =            new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);                int[] R, G, B;        /* Here you initialize R,G,B */        int[] pixels = new int[256*256];                // Fill array with color values        for ( int x = 0; x != 256; ++x )        {            for ( int y = 0; y != 256; ++y )            {                int i = 256*y+x;                pixels = makeRGB(R, G, B);            }        }                // Write colors to image        image.setRGB(0, 0, 256, 256, pixels, 0, 256);                return image;    }    // r,g,b should be >= 0 and <= 255, otherwise    // you will get strange results    private static int makeRGB(int r, int g, int b)    {        return (0xFF << 24) | (r << 16) | (g << 8) | b;    }        // grayLevel should be >=0 and <255.    // 0 gives black, 255 white.    private static int makeGray(int grayLevel)    {        return makeRGB(grayLevel, grayLevel, grayLevel);    }}


Also keep in mind that your R, G and B arrays should only contain values ranging from 0 to 255, otherwise color components overlap and you get strange results (as shown in my previous post).

For example, using
R = i/255*255;G = R/255;B = (R+ G)/255;

will certainly not produce values for R (and B) that are all between 0 and 255.

[Edited by - SamLowry on December 29, 2004 9:06:34 AM]
Mary Coory
Mary Coory

Thanks million SamLowry.

I do really appreciate how you let me understand the work step by step . God bless you :).

the code works fine with me now :). I add App as a class in my main program as I showed here. method generateRGB generate the three
arrays R[],G[],B[] in the main program. I want to konw how to use these arrays in the class App which I call in the method doViewImage() ??

My second question is if I save the image using:

/* Save it to file */
try
{
ImageIO.write( image, "PNG", new File("output.png") );
}
catch ( IOException e )
{
// Something bad happened
System.out.println(e);
}

and I want to extract the pixels again from the image. How can I do that????



Here is how my program looks like:

......

public class ft extends JFrame {

public static void main(String[] args) {

new ft();
}


.......

int XX = 256*256 ;
int[] R, G, B;




public ft() {



........

R = new int [XX];
G = new int [XX];
B = new int [XX];
}

....
....




public void generateRGB()
{
....
R[Pi] = Pi/(256*256);
G[Pi] = ( Pi - (256 * 256 * R[Pi]) ) / 256;
B[Pi] = ( Pi - (256 * 256 * R[Pi]) ) - (256*G[Pi]);
Pi++;
...
}




public void doViewImage()
{

App viewImage ;
viewImage = new App();

}

...
}


class App
{

App ()
{
BufferedImage image = paintImage();
ImageWindow wnd = new ImageWindow(image);
wnd.setVisible(true);
}


public static BufferedImage paintImage()
{
int XX = 256*256 ;
int[] R, G, B;
R = new int [XX];
G = new int [XX];
B = new int [XX];

/* for (int i=0; i<= 255*255; i++)
{ R = i/(256*256) ;
G = (i - (256 * 256 * R)) / 256 ;
B = (i - (256 * 256 * R)) - (256*G) ;
} */

BufferedImage image =
new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);


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

// Fill array with color values
for ( int x = 0; x != 256; ++x )
{
for ( int y = 0; y != 256; ++y )
{
int index = 256*y+x;
pixels[index] = (0xFF << 24) | (x * y + 100); //makeRGB(R[index], G[index], B[index]); //(0xFF << 24) | (x * y + 100);
}
}


// Write colors to image
image.setRGB(0, 0, 256, 256, pixels, 0, 256);

return image;
}

// r,g,b should be >= 0 and <= 255, otherwise
// you will get strange results
private static int makeRGB(int r, int g, int b)
{
return (0xFF << 24) | (r << 16) | (g << 8) | b;
}

}

What shall I do to let class App to read the values of R[],G[],B[] from method generateRGB ?

SamLowry
SamLowry
First of all, if you post code, would you mind using the tags (Forum FAQ); it's rather hard to read unindented code.


Second question:
Reading a PNG is done with the same class as reading, namely ImageIO.
BufferedImage image = null;try{    image = ImageIO.read( new File("image.png") );}catch ( IOException e ){    System.out.println(e);}




Other question:
You're confusing me with your code listing. You left out parts which might contain important things; for example, your "ft" class extends from JFrame, meaning that it represents a window, which may or may not be shown. I suppose somewhere you create an App object which again creates a window and uses it to show an image.

From within the App class, you can't access generateRGB without an "ft" instance, so you have to pass App the "ft" instance from "ft" or something similar, but this is of no importance because it doesn't make a lot of sense.

I suggest you re-evaluate what you are trying to do; also re-evaluate your code and see if you understand what it does and how it does it, and clean it up a bit.



Also, assuming Pi goes from 0 to 256*256-1
R[Pi] = Pi/(256*256);G[Pi] = ( Pi - (256 * 256 * R[Pi]) ) / 256;B[Pi] = ( Pi - (256 * 256 * R[Pi]) ) - (256*G[Pi]);Pi++;

All R values will be 0.
Mary Coory
Mary Coory
Good Day SamLowry;

I'm sorry for posting unindented code. I don't know how to that.

I know what I want from my project. First I want to learn about how to generate image and you taught me that very clearly so I tried to apply it in my project and it was run correctly.

My project idea is to read a text then store unrepeated words in an array, then using the index of this array I will generate pixels as R[], G[], and B[], then extract the text again from the image.

I re-evaluate and change my code to be more understandable and posted here:
and I also tried to extract pixel from the image using pixelGrabber as I read about but still not get correct result:

Here is my complete code so far:

import java.io.*;import javax.swing.*;import java.util.*;import javax.imageio.*;import java.awt.*;import java.applet.Applet;import java.awt.event.*;import java.awt.image.*;import javax.swing.*;public class ft extends JFrame  {   public static void main(String[] args) {             new ft();   }      private JTextArea text;  // Holds the text that is displayed in the window.   demoframe Imagewindow;   public int index=0;   String textArray[];   int rawHeight =256 ;   int rawWidth = 256;  int [] myPixels = new int[rawWidth * rawHeight];   // double R[], G[], B[];       Image rawImage;         int XX = 256*256 ;        int[] R, G, B;                        public ft() {                            super(" Text Editor");      setJMenuBar(makeButtons());      text = new JTextArea("<<Insert text here>>",25,50);     // text = new JTextField(20);      text.setBackground(Color.white);      text.setMargin( new Insets(3,5,0,0) );      JScrollPane scroller = new JScrollPane(text);      setContentPane(scroller);      setDefaultCloseOperation(EXIT_ON_CLOSE);      pack();      setLocation(50,50);      show();            Imagewindow = new demoframe("Compressed Text Window");      Imagewindow.resize(500,500);              R = new int [XX];        G = new int [XX];        B = new int [XX];}      private JMenuBar makeButtons() {       ActionListener listener = new ActionListener() {                 public void actionPerformed(ActionEvent evt) {               String cmd = evt.getActionCommand();                               if (cmd.equals("CLEAR"))                  doNew();               if (cmd.equals("OPEN"))                  doOpen();               if (cmd.equals("SAVE"))                  doSave();               if (cmd.equals("COMPRESS TEXT"))               {  doCompress();               }                               if (cmd.equals("VIEW IMAGE"))                 {                      //hide();                   doViewImage();               }               if (cmd.equals("QUIT"))                  doQuit();            }         };               JButton ClearButton = new JButton("CLEAR");      ClearButton.setEnabled( true );      ClearButton.addActionListener(listener);            JButton OpenButton = new JButton("OPEN");      OpenButton.setEnabled( true );      OpenButton.addActionListener(listener);               JButton SaveButton = new JButton("SAVE");      SaveButton.setEnabled( true );      SaveButton.addActionListener(listener);            JButton QuitButton = new JButton("QUIT");      QuitButton.setEnabled( true );      QuitButton.addActionListener(listener);                 JButton CompressButton = new JButton("COMPRESS TEXT");      CompressButton.setEnabled( true );      CompressButton.addActionListener(listener);                 JButton HideImageButton = new JButton("VIEW IMAGE");      HideImageButton.setEnabled( true );      HideImageButton.addActionListener(listener);            JMenuBar bar = new JMenuBar();      bar.add(ClearButton);      bar.add(OpenButton);      bar.add(SaveButton);      bar.add(CompressButton);      bar.add(HideImageButton);      bar.add(QuitButton);            return bar;   }   private void doNew() {        text.setText("");   }   private void doSave() {      File file;         JFileChooser fd;       fd = new JFileChooser(new File("."));      fd.setDialogTitle("Save Text As...");      int action = fd.showSaveDialog(this);      if (action != JFileChooser.APPROVE_OPTION) {         return;      }      file = fd.getSelectedFile();      if (file.exists()) {         action = JOptionPane.showConfirmDialog(this,                     "Replace existing file?");         if (action != JOptionPane.YES_OPTION)            return;      }      try {         PrintWriter out = new PrintWriter(new FileWriter(file));         String contents = text.getText();         out.print(contents);         if (out.checkError())            throw new IOException("Error while writing to file.");         out.close();      }      catch (IOException e) {        JOptionPane.showMessageDialog(this,             "Sorry, an error has occurred:\n" + e.getMessage());      }   }   private void doOpen() {      File file;         JFileChooser fd; // File dialog              fd = new JFileChooser(new File("."));      fd.setDialogTitle("Open File...");      int action = fd.showOpenDialog(this);      if (action != JFileChooser.APPROVE_OPTION) {          return;      }      file = fd.getSelectedFile();      try {         TextReader in = new TextReader(new FileReader(file));          String line;         text.setText("");         int lineCt = 0;         while (lineCt < 1000 && in.peek() != '\0') {            line = in.getln();            text.append(line + '\n');            lineCt++;         }         if (in.eof() == false)         text.append("\n\n******* Text truncated to 1000 lines! *******\n");         in.close();      }      catch (Exception e) {        JOptionPane.showMessageDialog(this,                "Sorry, some error occurred:\n" + e.getMessage());      }   } 	//public Image doCompress()         public void doCompress()	{		String tempText, tempToken;		int allWords, textSize=0, arrayTS=0, Pi=0, foundIn=0;		textArray = new String[1000];		//myPixel = new int[10000];		//R = new double[10000];		//G = new double[10000];		//B = new double[10000];                Image generatedImage;                   		tempText = text.getText();		//System.out.println(tempText);		        StringTokenizer tokens = new StringTokenizer( tempText );				allWords=tokens.countTokens();				//System.out.println(allWords);					while ( tokens.hasMoreTokens() )		{			tempToken=tokens.nextToken();			textSize+=tempToken.length();						foundIn=linearSearch(textArray,tempToken);						if(foundIn==(-1))			{ 				textArray[index]=tempToken;            	myPixels[Pi]=index;            //	System.out.println( textArray[index] + "\n" );            	arrayTS+=textArray[index].length();            	index++;            	        	}//if        	else{        		myPixels[Pi]=foundIn;        	}                        //Convert the indices into a Pixel(RGB)        	         	R[Pi] =  myPixels[Pi]/(256*256);        	G[Pi] = ( myPixels[Pi] - (256 * 256 * R[Pi]) ) / 256;        	B[Pi] = ( myPixels[Pi] - (256 * 256 * R[Pi]) ) - (256*G[Pi]);        	Pi++;        }//while                     System.out.println("All Words="+allWords+"\nDiff Words="+ index+"\n");     System.out.println("Actual Text Size="+textSize+" bytes");     System.out.println("Compressed Text Size="+(3*allWords+arrayTS)+" bytes");   }// doCompress      public int linearSearch( String array[], String key )    {         for ( int n = 0; n < index; n++ )          //if ( array[ n ] == key )         if( array[ n ].compareTo( key )==0 )            return n;      return -1;   }   public void doViewImage()    {               App viewImage ;       viewImage = new App();        }     private void doQuit()    {      System.exit(0);   }}  class demoframe extends Frame {	Label label1; demoframe(String title){     super(title);     setLocation(100,100);     ImageIcon image = new ImageIcon("output.bmp");     JLabel label = new JLabel();     label.setIcon(image);     add(label);}}/*************************************************************************/class App extends JFrame{     ImageWindow wnd;       App ()    {       BufferedImage image = paintImage();       ImageWindow wnd = new ImageWindow(image);            wnd.setJMenuBar(makeButtons());       //wnd.show();       wnd.setVisible(true);           }    private JMenuBar makeButtons() {       ActionListener listener = new ActionListener() {                 public void actionPerformed(ActionEvent evt) {               String cmd = evt.getActionCommand();                               if (cmd.equals("Extract Text")) {}                                  if (cmd.equals("QUIT")){                  doQuitImage();                 }            }         };               JButton ExtractButton = new JButton("Extract Text");      ExtractButton.setEnabled( true );      ExtractButton.addActionListener(listener);                JButton QuitButton = new JButton("QUIT");      QuitButton.setEnabled( true );      QuitButton.addActionListener(listener);                             JMenuBar bar = new JMenuBar();      bar.add(ExtractButton);      bar.add(QuitButton);            return bar;   }      private void doQuitImage()    {      //wnd.setVisible(false);      System.exit(0);   }        public static BufferedImage paintImage()    {       int XX = 256*256 ;        int[] R, G, B;        R = new int [XX];        G = new int [XX];        B = new int [XX];        Image image_in_file;                 for (int i=0; i<= 255*255; i++)        {       R = i/(256*256) ;        	G = (i - (256 * 256 * R)) / 256 ;        	B = (i - (256 * 256 * R)) - (256*G) ;        }                 BufferedImage image =            new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);                int[] pixels = new int[256*256];                // Fill array with color values        for ( int x = 0; x != 256; ++x )        {            for ( int y = 0; y != 256; ++y )            {                int index = 256*y+x;                pixels[index] = makeRGB(R[index], G[index], B[index]); //(0xFF << 24) | (x * y + 100);            }        }                // Write colors to image        image.setRGB(0, 0, 256, 256, pixels, 0, 256);        try{ ImageIO.write(image,"JPG", new File("output.JPG"));}                 catch (IOException e) {System.out.println(e);}        //image_in_file = createImage(new MemoryImageSource(256, 256, pixels,0,256));  int bitMap [];                         bitMap  = new int [256*256];        // U have to use image generated up                          PixelGrabber pg = new PixelGrabber(image,0,0,256,256,bitMap,0,256);         try{            pg.grabPixels();        } catch (InterruptedException e) {         e.printStackTrace ();        // return;        }        if ((pg.getStatus() & ImageObserver.ABORT) != 0)        { System.err.println("Pixel grab not successful");        //  return;        }         for ( int x = 0; x != 256; ++x )        {            for ( int y = 0; y != 256; ++y )            {                int index = 256*y+x;                int pixel = bitMap[index];                // u have to use R[], G[], B[]                 int alpha = (pixel >> 24) & 0xFF;                 R[index] = (pixel >> 16) & 0xFF;                  G[index] = (pixel >> 8) & 0xFF;                  B[index] = (pixel  ) & 0xFF;                 int Windex = (256 * 256)* R[index] + 256 * G[index] + B[index];                             }        }         return image;    }    // r,g,b should be >= 0 and <= 255, otherwise    // you will get strange results    private static int makeRGB(int r, int g, int b)    {        return (0xFF << 24) | (r << 16) | (g << 8) | b;    }    }/**************************************************************************//*class extractPixel{       extractPixel ()    {               } private static void extractPixels()    {         int bitMap [];                         bitMap  = new int [256*256];        // U have to use image generated up        Image image;                  PixelGrabber pg = new PixelGrabber(image,0,0,256,256,bitMap,0,256);         try{            pg.grabPixels();        } catch (InterruptedException e) {         e.printStackTrace ();         return;        }        if ((pg.getStatus() & ImageObserver.ABORT) != 0)        { System.err.println("Pixel grab not successful");          return;        }         for ( int x = 0; x != 256; ++x )        {            for ( int y = 0; y != 256; ++y )            {                int index = 256*y+x;                int pixel = bitMap[index];                // u have to use R[], G[], B[]                 int alpha = (pixel >> 24) & 0xFF;                 int red = (pixel >> 16) & 0xFF;                  int green = (pixel >> 8) & 0xFF;                  int  blue = (pixel  ) & 0xFF;            }        }    }      } */


and I also use this ready class :
[source = "cpp"]/*       This file defines the Class TextReader as a subclass of FilterReader..    The TextReader provides methods for reading data expressed in human-readable    ASCII text format.        This file also defines three public subclasses of RuntimeException to represent    errors that can occur during input.  These classes are static nested inside the    TextReader class.        This is a modest variation on an earlier class called AsciiInputStream, which served    a similar function for Java 1.0, where InputStreams are used instead of Readers    for character input.        David Eck    August 18, 1998    */   import java.io.*;public class TextReader extends FilterReader {    // ************************** Exception Classes *******************************		// First, define the exceptions that can be thrown by this class.  These exceptions		// are subclasses of RuntimeException, so they do not require mandatory error-handling.		// Also, if you prefer, you can turn off excpetions by calling the IOCheck() method.		// In that case, when an exception occurs during processing by one of the methods		// of the TextReader class, an errorFlag is set but no exception is thrown.		// If you use this alternative error-handling strategy, then you should call the		// checkError() method after each input operation to see whether the operation		// completed successfully.		public static class Error extends RuntimeException {		      // Represents any excpetion that occurs in the TextReader Class.		      // In fact, only general IOExceptions are translated directly into		      // TextReader.Error.  Other exceptions throw objects belonging		      // to one of the following subclasses of TextReader.Error.		   Error(String errorMessage) {		      super(errorMessage);		   }		}		public static class FormatError extends Error {		      // Illegal data: an illegal number or an illegal boolean value		   FormatError(String errorMessage) {		      super(errorMessage);		   }		}		public static class EOFError extends Error {		     // attempt to read past end of stream		   EOFError(String errorMessage) {		      super(errorMessage);		   }		}   // ***************************** Constructors ********************************      public TextReader(BufferedReader s) {      super(s);   }      public TextReader(Reader s) {      super(new BufferedReader(s));   }      public TextReader(InputStream s) {      super( new BufferedReader(new InputStreamReader(s)) );   }      // ***************************** Error Checking *****************************   public void IOCheck(boolean throwExceptions) {  // call IOCheck(false) to turn      throwExceptionOnError = throwExceptions;     //   off exceptions, then check   }                                               //   for errors by calling checkError()      public boolean error() {   // returns true if the most recent input operation on      return errorFlag;       // this TextReader produced an error.  An error   }                          // message can be retrieved by calling getErrorMessage()      public String getErrorMessage() {            // if the most recent operation on      return errorFlag ? errorMessage : null;   // this TextReader produced an error, this   }                                            // gets an error message for that error   // *************************** Input Methods ********************************         // peek()  -- returns the next character about to be read from the stream,      //     without removing it from the stream.  '\n' is returned if the next      //     thing in the stream is end-of-line.  '\0' is returned if the next      //     thing is end-of-file.  (There is no way for peek() to distinguish      //     between EOF and a null character in the input data.  Use eof() to      //     test for end-of-file.)            // getAnyChar() -- reads and returns the next character in the stream, even if it      //     is a whitespace character.  It is an error to read past end-of-file.      //     (Note that getChar() skips over whitespace characters before reading.)            // getChar(), getByte(), etc. -- skip over whitespace characters, then try to read a      //     value of the specified type.  An error can occur if the right type of data      //     is not found.  A "word" is any sequence of non-whitespace characters.      //     A "boolean" is one of the words (ignoring case) "true", "false", "yes", "no"      //     "t", "f", "y", "n", "0", "1".  An "Alpha" is a sequence of letters.  getAlpha()      //     is a special case in that it will skip over all non-letters before reading,      //     rather than just skipping whitespace characters.            // getln() -- reads all characters up to the next end-of-line and returns them      //     as a String.  The end-of-line is then read and discarded.            // getlnChar(), getlnByte() etc. -- Work the same as getChar(), etc., except that      //     after the value is read, any other characters on the same line, including the      //     end-of-line, are read and discarded.            // eoln() -- this first reads and discards any spaces and tabs.  Then tests whether      //     the next thing in the stream is an end-of-line.  The end-of-file also counts      //     as an end of line.  If you want to test for eoln without discarding spaces      //     and tabs, check whether peek() == '\n' or '\0'.         // eof() -- this first reads and discards any spaces, ends-of-line and tabs.  Then tests      //     whether the next thing in the stream is the end-of-file.  If you want to test for      //     eof without discarding spaces, ends-of-line, and tabs, check whether peek() == '\0'.            // skipWhiteSpace() -- reads and discards any whitespace characters (spaces, tabs, and      //     end-of-lines).  Stops when the next character is a non-whitespace character or is eof.            // skipNonLetters() -- reads and discards any non-letters, stopping when the next character      //     is a letter or the end-of-file.      public char peek()          { errorFlag = false; return lookChar(); }      public char getAnyChar()    { errorFlag = false; return readChar(); }   public char getChar()       { errorFlag = false; skipWhiteSpace(); return readChar(); }   public byte getByte()       { errorFlag = false; return (byte)readInteger(-128L,127L); }   public short getShort()     { errorFlag = false; return (short)readInteger(-32768L,32767L); }      public int getInt()         { errorFlag = false; return (int)readInteger((long)Integer.MIN_VALUE, (long)Integer.MAX_VALUE); }   public long getLong()       { errorFlag = false; return readInteger(Long.MIN_VALUE, Long.MAX_VALUE); }   public float getFloat()     { errorFlag = false; return readFloat(); }   public double getDouble()   { errorFlag = false; return readDouble(); }   public boolean getBoolean() { errorFlag = false; return readBoolean(); }   public String getWord()     { errorFlag = false; return readWord(); }   public String getAlpha()    { errorFlag = false; return readAlpha(); }      public String getln()         { errorFlag = false; return readLine(); }   public char getlnChar()       { char x=getChar();       dropLine();  return x; }   public byte getlnByte()       { byte x=getByte();       dropLine();  return x; }   public short getlnShort()     { short x=getShort();     dropLine();  return x; }   public int getlnInt()         { int x=getInt();         dropLine();  return x; }   public long getlnLong()       { long x=getLong();       dropLine();  return x; }   public float getlnFloat()     { float x=getFloat();     dropLine();  return x; }   public double getlnDouble()   { double x=getDouble();   dropLine();  return x; }   public boolean getlnBoolean() { boolean x=getBoolean(); dropLine();  return x; }   public String getlnWord()     { String x=getWord();     dropLine();  return x; }   public String getlnAlpha()    { String x=getAlpha();    dropLine();  return x; }      public boolean eoln() {      char ch = lookChar();      while (!EOF && !errorFlag && (ch == ' ' || ch == '\t')) {         readChar();         ch = lookChar();      }      return (ch == '\n' || EOF);   }      public boolean eof() {      char ch = lookChar();      while (!EOF && !errorFlag && (ch == ' ' || ch == '\n' || ch == '\t')) {         readChar();         ch = lookChar();      }      return EOF;   }      public void skipWhiteSpace() {      char ch = lookChar();      while (!errorFlag && (ch == ' ' || ch == '\n' || ch == '\t')) {         readChar();         ch = lookChar();      }   }      public void skipNonLetters() {      char ch = lookChar();      while (!errorFlag && !EOF && !Character.isLetter(ch)) {         readChar();         ch = lookChar();      }   }      public void close() {      errorFlag = false;      try {         in.close();      }      catch (IOException e) {         errorFlag = true;         errorMessage = e.toString();      }   }   // *************************** private implementation stuff ***********************      private int lookAhead = -1;          // one-character buffer; -1 indicates the buffer is empty   private boolean errorFlag = false;    // set to true if most recent operation produced an error   private String errorMessage = "";     // error message for the most recent error   private boolean EOF = false;          // has the end-of-stream been encountered?   private boolean throwExceptionOnError = true;  // determines which type of error-handling is used      // Three utility routines for throwing exceptions.      private void doError(String message) {      errorFlag = true;      errorMessage = message;      if (throwExceptionOnError)         throw new Error(message);   }      private void doFormatError(String message) {      errorFlag = true;      errorMessage = message;      if (throwExceptionOnError)         throw new FormatError(message);   }      private void doEOFError(String message) {      errorFlag = true;      errorMessage = message;      if (throwExceptionOnError)         throw new FormatError(message);   }      // The remaining methods are basic methods for reading the various types of   // data from the stream      private char readChar() {      char ch = lookChar();      if (EOF)         doEOFError("Attempt to read past end-of-data in input stream.");      lookAhead = -1;      return ch;   }      private boolean possibleLineFeedPending = false;  // for dealing with \r\n pairs      private char lookChar() {      if (lookAhead != -1) {         if (lookAhead == '\r')            return '\n';         else           return (char)lookAhead;      }      if (EOF)         return '\0';      try {         int n = in.read();         if (n == '\n' && possibleLineFeedPending) {  // ignore \n of \r\n pair            n = in.read();         }         possibleLineFeedPending = (n == '\r');         lookAhead = n;         if (lookAhead == -1) {            EOF = true;            return '\0';         }      }      catch (IOException e) {         doError(e.getMessage());      }      if (lookAhead == '\r')  // represent all eoln's with \n         lookAhead = '\n';      return (char)lookAhead;   }      private void dropLine() {      while (!errorFlag) {         if (lookChar() == '\0')            return;         if (readChar() == '\n')            return;      }   }      private String readLine() {      StringBuffer s = new StringBuffer(100);      char ch = readChar();      while (!errorFlag && ch != '\n') {         s.append(ch);         ch = lookChar();         if (ch == '\0')            break;         ch = readChar();      }      return s.toString();   }      private String readWord() {      skipWhiteSpace();      if (errorFlag)         return null;      StringBuffer s = new StringBuffer(50);      char ch = lookChar();      if (EOF) {         doEOFError("Attempt to read past end-of-data");         return null;      }      while (!errorFlag && !EOF && ch != '\n' && ch != ' ' && ch != '\t') {         s.append(readChar());         ch = lookChar();      }      return s.toString();   }         private String readAlpha() {      skipNonLetters();      if (errorFlag)         return null;      StringBuffer s = new StringBuffer(50);      char ch = lookChar();      if (EOF) {         doEOFError("Attempt to read past end-of-data");         return null;      }      while (!errorFlag && Character.isLetter(ch)) {         s.append(readChar());         ch = lookChar();      }      return s.toString();   }         public float readFloat() {      double d = readDouble();      if (errorFlag)         return Float.NaN;      if (Math.abs(d) > Float.MAX_VALUE)         doFormatError("Input number outside of legal range for values of type float");      return (float)d;   }      public double readDouble() {      double x = Double.NaN;      StringBuffer s=new StringBuffer(50);      skipWhiteSpace();      char ch = lookChar();      if (ch == '-' || ch == '+') {          s.append(readChar());          skipWhiteSpace();          ch = lookChar();      }      if ( (ch < '0' || ch > '9') && (ch != '.') ) {         if (EOF)            doEOFError("Expecting a floating-point number and found end-of-data");         else            doFormatError("Expecting a floating-point number and found \""  + ch + "\"" );         return Double.NaN;      }      boolean digits = false;      while (ch >= '0' && ch <= '9') {          s.append(readChar());          ch = lookChar();          digits = true;      }      if (ch == '.') {         s.append(readChar());         ch = lookChar();         while (ch >= '0' && ch <= '9') {             s.append(readChar());             ch = lookChar();             digits = true;         }      }      if (!digits) {         doFormatError("No digits found in floating-point input.");         return Double.NaN;      }      if (ch == 'E' || ch == 'e') {         s.append(readChar());         ch = lookChar();         if (ch == '-' || ch == '+') {             s.append(readChar());             ch = lookChar();         }         if ( (ch < '0' || ch > '9') && (ch != '.') ) {            if (EOF)               doEOFError("Expecting exponent for a floating-point number and found end-of-data");            else               doFormatError("Expecting exponent for a floating-point number and found \""  + ch + "\"");            return Double.NaN;         }         while (ch >= '0' && ch <= '9') {             s.append(readChar());             ch = lookChar();         }      }      String str = s.toString();      Double d;      try {         d = new Double(str);         x = d.doubleValue();      }      catch (NumberFormatException e) {         x = Double.NaN;      }      if (Double.isNaN(x) || Double.isInfinite(x)) {         doFormatError("Illegal floating point number");         return Double.NaN;      }            return x;   }      public boolean readBoolean() {      boolean ans = false;      String s = getWord();      if (errorFlag)         return false;      if ( s.equalsIgnoreCase("true") || s.equalsIgnoreCase("t") ||                 s.equalsIgnoreCase("yes")  || s.equalsIgnoreCase("y") ||                 s.equals("1") ) {           ans = true;       }       else if ( s.equalsIgnoreCase("false") || s.equalsIgnoreCase("f") ||                 s.equalsIgnoreCase("no")  || s.equalsIgnoreCase("n") ||                 s.equals("0") ) {           ans = false;       }       else          doFormatError("Illegal input for value of type boolean: \"" + s + "\"");       return ans;   }   private long readInteger(long min, long max) {  // read long integer, limited to specified range      skipWhiteSpace();      if (errorFlag)         return 0;      char sign = '+';      if (lookChar() == '-' || lookChar() == '+') {         sign = getChar();         skipWhiteSpace();      }      long n = 0;      char ch = lookChar();      if (ch < '0' || ch > '9') {         if (EOF)            doEOFError("Expecting an integer and found end-of-data");         else            doFormatError("Expecting an integer and found \""  + ch + "\"");         return 0;      }      while (!errorFlag && ch >= '0' && ch <= '9') {         readChar();         n = 10*n + (int)ch - (int)'0';         if (n < 0) {            doFormatError("Integer value outside of legal range");            return 0;         }         ch = lookChar();      }      if (sign == '-')         n = -n;      if (n < min || n > max) {         doFormatError("Integer value outside of legal range");         return 0;      }      return n;   }      // Override the read() methods from FilterReader so that they will work if a   // TextReader is wrapped inside another file.  (This is necessary to take   // lookAhead into account.)      public int read() throws IOException {      if (lookAhead == -1)         return super.read();      else {         int x = lookAhead;         lookAhead = -1;         return x;      }   }      public int read(char[] buffer, int offset, int count) throws IOException {      if (lookAhead == -1 || count <= 0)         return super.read(buffer,offset,count);      else if (count == 1) {         buffer[offset] = (char)lookAhead;         lookAhead = -1;         return 1;      }      else {         buffer[offset] = (char)lookAhead;         lookAhead = -1;         int ct = super.read(buffer,offset+1,count-1);         return ct + 1;      }   }   } // end of class TextReader


[Edited by - Mary Coory on December 29, 2004 4:52:42 PM]
SamLowry
SamLowry
Make sure you save using a lossless format (TGA, PCX, BMP, PNG), and don't try using a lossy one (JPG). A lossy format will only save an approximation, which is ok for photographs, but certainly not for your purposes.


Also, you're complicating your color conversion. You have an integer, you split it up in 3 components, and merge them back together afterwards. The only thing you need to do is add the 0xFF for the alpha channel.

// Works as long as 0 <= myPixels[Pi] < 2^24int finalPixel = myPixels[Pi] | (0xFF << 24);



As for the PixelGrabber: the ImageIO.read method returns a BufferedImage, which provides a getRGB(x,y) method; I think this would be a lot simpler than using a PixelGrabber (assuming of course that it works...)

[Edited by - SamLowry on December 29, 2004 5:13:20 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.