Accessing pixels

How can i access pixels of an image and manipulate them (change their RGB). I think pixelGrabber does this but how? any simple working ex.

Thanks in advance.
LVL 1
m_adilAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

samersCommented:
yes u r right by ur guess about pixelGrabber.
all what u have to do is creat new instance of PixelGrabber :
PixelGrabber pg = new PixelGrabber(img,x,y,width,height,inforceRBG)
where the contructor take as parameter:
-img of type Image, whixh is the image u want to get its pixels.
-x,y,width,height, of type int, whch is the rectangle of the image u want to grab its pixels
-inforceRBG of type boolean, to inforce RBG.

after instantiation u call grabPixels() method:
pg.grabPixels();
and u can check for the type of the image or the color model by calling the method
getColorModel()
ColorModel cm = pg.getColorModel();
, which return an object of type ColorModel.
to get the pixels of the image u must call the method
getPixels()
Object pixels = pg.getPixels();
wich return an object of type Object.
ofcourse if u want to manipulate these pixels u should store them in array, but u should know the type of array before u store them in the array.
to do so , check the type of the returned pixels from getPixels() method if they are of instanceof byte[] or   int[],
if (pixels instanceof byte[]){
    byte[] bPixels = new byte[width*height]; //the width and height of the image
System.arraycopy(pixels,0,bpixels,0,width*height);
}
else if (pixels instanceof int[]){
  int[] iPixels = new int[height*width];
System.arraycopy(pixels,0,ipixels,0,width*height);
}

and now the pixels of ur image are stored at either bPixels or iPixels,
and ofcourse there r other methods u can benefit from.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
heyhey_Commented:
sampel code from
http://www.experts-exchange.com/Computers/Programming/Languages/Java/Q_10242582.html

this exampel changes the alpha value of all pixels that have some fixed color (makes them transparent)

/*
sample code
all you need is one image (I use duke.gif from Swing examples)
inside the current directory.
compile this example and run it - that's all.
*/
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
public class demo1 extends Container
{
  private Image bgImage;
  private Image i, i1, i2, i3;
 
  public demo1()
  {
    loadImages();
    doSomeConversion();
    buildUI();
  }
  // load one background image
  // and one sample foreground that we will manipulate
  public void loadImages()
  {  
    setBackground(Color.lightGray);
    i = Toolkit.getDefaultToolkit().getImage("duke.gif");
    bgImage = Toolkit.getDefaultToolkit().getImage("aa.jpg");
    MediaTracker tracker = new MediaTracker(this);
    tracker.addImage(i, 11);
    tracker.addImage(bgImage, 11);
    try
    {
      tracker.waitForID(11);
    } catch (Exception x)
    {
      x.printStackTrace();
    }
    System.out.println("w = " + i.getWidth(null));
    System.out.println("w = " + bgImage.getWidth(null));
  }
  // create three copies of the sampel Image with different aplha values
  public void doSomeConversion()
  {
    i1 = convertToTransparentImage(i, 0, 0);
    i2 = convertToTransparentImage(i, 0, 128);
    i3 = convertToTransparentImage(i, 0, 255);
  }  
 
  // create one background Image container
  // and add 4 Image componets on it
  public void buildUI()
  {
    setLayout(new GridLayout(1, 1));
    // try with Image background
//    ImageContainer c = new ImageContainer(bgImage);
    // or try with Panel with fixed background color
    Panel c = new Panel();
    c.setBackground(Color.cyan);
    c.setLayout(new FlowLayout());
    add(c);
    ImageContainer cc = new ImageContainer(i);
    c.add(cc);
    cc = new ImageContainer(i1);
    c.add(cc);
    cc = new ImageContainer(i2);
    c.add(cc);
    cc = new ImageContainer(i3);
    c.add(cc);
  }
 
  // your method
  public Image convertToTransparentImage(Image image, int r, int g, int b, int alpha)
  {
    return convertToTransparentImage(image, (r << 16 | r << 8 | b), alpha);
  }
  // your method with less parameters
  public Image convertToTransparentImage(Image image, int rgb, int alpha)
  {
    int w = image.getWidth(null);
    int h = image.getHeight(null);
    int[] pixels = new int[w * h];
   
    // grab all pixels with PixelGrabber
    PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
    try
    {
      pg.grabPixels();
    } catch (Exception x)
    {
      x.printStackTrace();
    }
    // change the alpha values if needed    
    for (int i = 0; i < w * h; i++)
    {
      int col = pixels[i] & 0xffffff;
      if (col== rgb)
      {
        System.out.print(".");
        pixels[i] = col | (alpha << 24);
      }
    }
    // create new Image object
    return createImage(new MemoryImageSource(w, h, pixels, 0, w));
  }
// some double buffering code  
  private Image offImage;
  private Graphics offGraphics;
 
  public void update (Graphics g)
  {
    paint(g);
  }
  public void paint (Graphics g)
  {
    Dimension d = getSize();
    if (offImage == null || offImage.getWidth(null) != d.width || offImage.getHeight(null) != d.height)
    {
      offImage = createImage(d.width, d.height);
      offGraphics = offImage.getGraphics();
    }
   
    offGraphics.setColor(getBackground());
    offGraphics.fillRect(0, 0, d.width, d.height);
    super.paint(offGraphics);
    g.drawImage(offImage, 0, 0, null);
  }
 
  // main method
  public static void main(String args[])
  {
    Frame f = new Frame("demo");
    f.add(new demo1());
    f.setSize(500, 500);
    f.setVisible(true);
    f.addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent e)
      {
        System.exit(0);
      }
    });
  }
 
  // helper class ImageContainer class :)
  class ImageContainer extends Container
  {
    private Image image;
    public ImageContainer(Image i)
    {
      image = i;
    }
    public Dimension preferredSize()
    {
      return new Dimension(image.getWidth(null), image.getHeight(null));
    }
    public Dimension minimumSize()
    {
      return super.minimumSize();
    }
    public Dimension getMaximumSize()
    {
      return preferredSize();
    }
    public void update(Graphics g)
    {
      paint(g);
    }
    public void paint(Graphics g)
    {
      g.drawImage(image, 0, 0, null);
      super.paint(g);
    }
  }
}
0
m_adilAuthor Commented:
wow great!
Plz give me a little time to check
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

m_adilAuthor Commented:
I've tried it. u'm getting a little problem. I've grabbed pixels by getPixels() method. Now i want to get RGB value of each pixel. how to do that?
I've tried
ColorModel cm=pg.getColorModel();
but it gives me an error ** Method getColorModel() not found in java.awt.image.PixelGrabber. **

Here is my code
********************
Image img;
..... //load image from file....

            int w = img.getWidth(null);
            int h = img.getHeight(null);
            int[] pixels = new int[w*h];
            int[] pixs = new int[w*h];
            
            PixelGrabber pg = new PixelGrabber(img, 0,0, w, h, pixels, 0, w);
            ColorModel cm=pg.getColorModel();            
            try {
                pg.grabPixels();
//                cm = pg.getColorModel();
            } catch (Exception x) {
                x.printStackTrace();
            }
            
            for(int i=0; i<w*h; i++) {
              /*  int r=cm.getRed(pixels[i]);
                int g=cm.getGreen(pixels[i]);
                int b=cm.getBlue(pixels[i]); */
          
                pixs[w*h-i-1] = pixels[i];
            }
            
            Image tmpimg = createImage(new MemoryImageSource(w,h,pixs,0,w));
            
            Graphics gg;
            gg = getGraphics();
            gg.drawImage(tmpimg, 0,0,null);

***************************


0
heyhey_Commented:
can't test it at the moment, but you need something like

PixelGrabber pg = new PixelGrabber(img, 0,0, w, h, pixels, 0, w);
try
{
  pg.grabPixels();
} catch (Exception x)
{
  x.printStackTrace();
}

for(int i=0; i<w*h; i++)
{
  int rgb = pixels[i];
  int a = (rgb >> 24) & 0xff;
  int r = (rgb >> 16) & 0xff;
  int g = (rgb >> 8)  & 0xff;
  int h = (rgb)       & 0xff;

}
0
samersCommented:
u should know about images more, and know how pixels are stored there, it depends on the number of colore the image use, for example, the example that used by heyhey, he assume that there's a byte for each single color, so when u need to get the RBG, u need to extract them from the pixel value.
so u had to know how many colors ur image has.
0
m_adilAuthor Commented:
I think i can find the no. of colors through Object pixels = pg.getPixels();
But as I've written above, the problem is that when i use ColorModel cm=pg.getColorModel();
it gives me an error ** Method getColorModel() not found in java.awt.image.PixelGrabber. **

Is there any other way to find the no. of colors?

Another thing is that when an image is using more than a byte for single pixel, then how to get RGB values?
0
heyhey_Commented:
' public synchronized ColorModel getColorModel()


Get the ColorModel for the pixels stored in the array. If the PixelGrabber was constructed with an explicit pixel buffer then this method will always return the default RGB ColorModel ...'

(so usually you don't need to use ColorModel at all)


> Another thing is that when an image
> is using more than a byte for single pixel,

Image usually uses INT (not BYTE) per pixel. red, green, blue and alpha values are packed inside that int.

why don't you just try my example ?
0
m_adilAuthor Commented:
heyhey thank u so much for ur help. Plz tell me one more thing. How to set pixel value from RGB value. i.e the reverse function of
  int rgb = pixels[i];
  int a = (rgb >> 24) & 0xff;  //blue
  int r = (rgb >> 16) & 0xff;  //red
  int g = (rgb >> 8)  & 0xff;  //green
  int h = (rgb)       & 0xff;  // ???
(what is h btw)
after changing rgb values how can i combine them to change pixels[i].

I've done this in c++ through
inline TColor rgb(int red,int green,int blue){return ((TColor)((blue)+(green<<8)+(red<<16)));};

but not sure how to do in java.
0
heyhey_Commented:
it's almost the same

int oldrgb = pixels[i];
int a = (rgb >> 24) & 0xff;  //blue
int r = (rgb >> 16) & 0xff;  //red
int g = (rgb >> 8)  & 0xff;  //green
int h = (rgb)       & 0xff;  // ???

int newrgb = (alpha << 24) | (red << 16) | (green << 8) | (blue);
// now newrgb == oldrgb :)

// or
// int newrgb = (alpha << 24) | (green << 16) | (red << 8) | (blue);
// change green and red

0
m_adilAuthor Commented:
yup its working.
Thanks alot.
0
heyhey_Commented:
so why did you accept samers's answer ?

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.