Jump to content
  • Advertisement
Sign in to follow this  
Koshmaar

[java] Updating Image after blurring

This topic is 4870 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys I'm trying to blur Image (loading goes ok), but changes I made to it, are not appearing on the screen. It's the method I'm using for blurring (actually, for debugging sake, it's just setting 150 for all pixels):

 Image image;

  public void Blur()
   {
   	
    int w = image.getWidth(null);
    int h = image.getHeight(null);
   	
    int [] pixels = new int[w * h];
    int [] newImage = new int[w * h];
   	
    PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
	
    try
     {
      pg.grabPixels();
     } 
	 
    catch (InterruptedException e)
     {
      System.err.println("interrupted waiting for pixels!");
     }
	 
    for (int j = 0; j < h; j++)	  
     for (int i = 0; i < w; i++)
      {	         
       newImage[j * w + i] = 150; 		 
      }           	
   
   // not updating as expected	
   image = createImage(new MemoryImageSource(w, h, newImage, 0, w));   	
   
   }




 public void paint(Graphics graphics)
   {
    graphics.drawImage(image, 0, 20, null);    
   }



I'm new in Java, and Googled few hours looking through various documentation sites, trying many different approaches - nothing worked. There's probably sth wrong with way I'm copying to image new pixels - I noticed, that after calling Blur(), picture isn't refreshed - ie. dragging sth on window leaves empty rectangles. Please help :-) [Edited by - Koshmaar on June 17, 2005 5:48:45 PM]

Share this post


Link to post
Share on other sites
Advertisement
Probably better place for this would be For begginners forum - if any moderator could move it... thx a lot!

Share this post


Link to post
Share on other sites
I think it belongs here. It's Java API specific so you'll get better help than in the beginner forum.

As far as your problem goes:

What's the code for the "createImage()" method? There's too little information to help right now.

Also, as you said dragging the screen causes empty rectangles. Try having your paint method looped so it's called multiple times.

Share this post


Link to post
Share on other sites
It's the createImage from Toolkit or Component.

1) You've forgot to post the fifth parameter to the MemoryImageSource constructor.

2) The Image api is threaded. You could try to use a MediaTracker to make sure the image is created before you use it. I still believe the designers were high when they dreamed up this moronic api.

3) If you don't need 1.1 compatibility it would be so much easier if you just used BufferedImages instead.

Share this post


Link to post
Share on other sites
Quote:
Quote: Funkapotamus
I think it belongs here. It's Java API specific so you'll get better help than in the beginner forum.


Yes, but since I got no reply in almost 1 hour, I thought that I'd get more replies in more public forum... but now, since you replied, there's no need to move it :-)

Quote:
Quote: Funkapotamus
Also, as you said dragging the screen causes empty rectangles. Try having your paint method looped so it's called multiple times.


I really doubt it would help - it seems that paint is called, but gives no result.


Tombr: fifth parameter has come back :-) it was just normal w.

Quote:
Quote: tombr
2) The Image api is threaded. You could try to use a MediaTracker to make sure the image is created before you use it. I still believe the designers were high when they dreamed up this moronic api.


OMG, it may be it - though, looking on google I've found ie. http://www.vijaymukhi.com/vmis/image4.html, and they aren't using MediaTracker. See:


public class zzz extends Applet
{ Image c;int k = 0;
int a[] = new int[10000];
ImageProducer p;
public void init ()
{ int n = 0;
for (int i = 0; i < 10000 ; i++)
a[n++]=0xffff0000;
p = new MemoryImageSource(100, 100, a, 0, 100);
c = createImage(p);
}
public void paint(Graphics g)
{ g.drawImage(c,0,0,this);
}
public boolean mouseDown(Event e,int x,int y)
{ k=k+10;
int n = 0;
ImageProducer q;
for (int i = 0; i < 10000 ; i++)
a[n++] = 0xff000000 | (k<<16);
q = new MemoryImageSource(100, 100, a, 0, 100);
c = createImage(q);
repaint();
showStatus("Value of k " + k);
return true;
}
}



They're calling repaint(), but for me it isn't working. Other site I visited: http://www.particle.kth.se/~fmi/kurs/PhysicsSimulation/Lectures/11A/pixelHandling.html, tomorrow I'll give it a try. Also, ImageProducer may be worth checking.

Quote:
Quote: tombr
3) If you don't need 1.1 compatibility it would be so much easier if you just used BufferedImages instead.


I don't need any compatibility, I just want this !@#$%%^&* program running ASAP. Thx for tip, I'll check also BufferedImage tomorrow, now it's too late here.

Share this post


Link to post
Share on other sites
Quote:

I'm new in Java, and Googled few hours looking through various documentation sites, trying many different approaches - nothing worked. There's probably sth wrong with way I'm copying to image new pixels - I noticed, that after calling Blur(), picture isn't refreshed - ie. dragging sth on window leaves empty rectangles.


I'm not sure I understand what your seeing but I'll say it anyway. Setting all the pixels to 150, you are setting the pixels to be transparent. So if the image disaper after you've blurred it, then that is correct. Try 0xff00007f instead of 150.

Share this post


Link to post
Share on other sites


Quote:

I'm not sure I understand what your seeing but I'll say it anyway. Setting all the pixels to 150, you are setting the pixels to be transparent. So if the image disaper after you've blurred it, then that is correct. Try 0xff00007f instead of 150.


OMG, you're right! :-)

I changed 150 to 0xff00007f and it gave me nice dark blue color :-) Also, I tried setting color to 0 - but nothing changed (I'm kinda used to old pascal convention, where 0 == black). Now I know that even using all BufferedImages, ImageProducers or anything else wouldn't help me... thx for help, ++rating for (both of) you :-)

Share this post


Link to post
Share on other sites
Hey man I am not sure if this will help at all but if you go to my old website:

http://www.wrathnut.freeservers.com/

And follow the link for the particle system tutorial you will see an example of image filtering, or blurring if you feel like calling it that. You can down load teh source and look at the imageSource object. In there is an extendable method for image filtering.

Anyway the reason that 0 != black is that java stores it's image color information packed into a hexadecimal format. This is the raw image data that you were refernceing. It is what teh pixel grabber grabs. Anyway tcolor format is as such:

0xAARRBBGG

0x ->Denotes a hexadecimal number system
AA ->The alpha value(this is how transparent the color is)
RR ->The red channel of teh color
GG ->The green channel of the color
BB ->The blue channel of the color

Basically you need to use bitwise operators to pack and unpack the color data.

Ahh heck here is the code from that class. It shows how to get the image information and work with it.


import java.applet.Applet;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.MemoryImageSource;

public class imageSource{
private int width, height, length;
private int[] source;
private static int[] filter;
private MemoryImageSource memSrc;
private Image img;

static{
//Simple low pass filter
filter = new int[]{ 1, 1, 1,
1, 1, 1,
1, 1, 1,
9};
}

imageSource(int width, int height, Applet app){
this.width = width;
this.height = height;
this.length = this.width * this.height;
this.source = new int [this.length];

for(int i=0; i < this.length; i++){
this.source = 0xFF000000;
}

this.memSrc = new MemoryImageSource(this.width, this.height, this.source, 0, this.width);
this.memSrc.setAnimated(true);
this.img = app.createImage(this.memSrc);

}

Image getImage(){
return this.img;
}

public void setPixel(int x, int y, Color c){
int pos = y*this.width + x;
//Check bounds
if(pos <= this.length && pos >= 0){
//If bounds check successful set pixel color
this.source[pos] = c.getRGB();
}
}

public void setSquare(int x, int y, int myWidth, int myHeight, Color c){
int l = x + myWidth;
int h = y + myHeight;

for(int i=x; i < l; i++){
for(int j=y; j < h; j++){
this.setPixel(i,j,c);
}
}
}

public void fadeImage(double percentage, Color c){
int r1, r2, g1, g2, b1, b2, dR, dG, dB, color;

color = c.getRGB();

//Find the fade channels
r1 = color & 0xFF0000;
g1 = color & 0xFF00;
b1 = color & 0xFF;

//amount of change per channel
dR = (int)(0xFF * percentage) << 16;
dG = (int)(0xFF * percentage) << 8;
dB = (int)(0xFF * percentage);

for(int i=0; i < this.length; i++){

color = this.source;

r2 = (color & 0xFF0000);
if(r2 != r1){//Make sure we haven't hit the faded color yet
//Apply color matching routine to the red channel
if(r2 < r1){r2 += dR;}
else{r2 -= dR;}
}
//Check bounds on the red channel
if(r2 < 0){r2 = 0;}
if(r2 > 0xFF0000){r2 = 0xFF0000;}

g2 = (color & 0xFF00);
if(g2 != g1){//Make sure we haven't hit the faded color yet
//Apply color matching routine to the green channel
if(g2 < g1){g2 += dG;}
else{g2 -= dG;}
}
//Check bounds on the Green channel
if(g2 < 0){g2 = 0;}
if(g2 > 0xFF00){g2 = 0xFF00;}

b2 = (color & 0xFF);
if(b2 != b1){//Make sure we haven't hit the faded color yet
//Apply color matching routine to the blue channel
if(b2 < b1){b2 += dB;}
else{b2 -= dB;}
}
//Check bounds on the Blue channel
if(b2 < 0){b2 =0;}
if(b2 > 0xFF){b2 = 0xFF;}

this.source = 0xFF000000|r2|g2|b2;
}

}

public void printFilter(){
for(int i =0; i < 10; i++){
System.out.println("filter[" + i + "]=" + filter);
}
}

public void filterImage(){

int tmpR, tmpG, tmpB, r2, g2, b2, pos, tmpPos, tCounter;

//Loop through the images source to apply the filter
for(int y=this.height-1; y > 0; y--){
for(int x=1; x < this.width-1; x++){
//Find the current pixel position
pos = y*this.width + x;

//Clear temp variables
tmpR = 0;
tmpB = 0;
tmpG = 0;
tCounter = 0;

for(int k=-1; k <= 1; k++){
for(int j=-1; j <= 1; j++){
//Find one of the surrounding pixel positions
tmpPos = (y+k)*this.width + (x+j);
//Make a bounds check
if(tmpPos >= 0 && tmpPos <this.length){

//Sum and multiply the surrounding pixel channels by their respective
//convolution coefficent
tmpR += ((this.source[tmpPos] & 0xFF0000) >> 16) * this.filter[tCounter];
tmpG += ((this.source[tmpPos] & 0xFF00) >> 8) * this.filter[tCounter];
tmpB += (this.source[tmpPos] & 0xFF) * this.filter[tCounter];
}
tCounter++;
}
}
//Divide summation by the filter's kernel
r2 = tmpR/this.filter[9];
//Bounds check this channel
if(r2 < 0){r2 = 0;}
if(r2 > 0xFF){r2 = 0xFF;}
//Bit shift some zeros in
r2 = r2 << 16;

//Divide summation by the filter's kernel
g2 = tmpG/this.filter[9];
//Bounds check this channel
if(g2 < 0){g2 = 0;}
if(g2 > 0xFF){g2 = 0xFF;}
//Bit shift some zeros in
g2 = g2 << 8;


//Divide summation by the filter's kernel
b2 = tmpB/this.filter[9];
//Bounds check this channel
if(b2 < 0){b2 = 0;}
if(b2 > 0xFF){b2 = 0xFF;}

//Set pixel color
this.source[pos] = 0xFF000000|r2|g2|b2;
}
}
}

public void flush(){
//this.memSrc.newPixels(0, 0, this.width, this.height);
this.memSrc.newPixels();
}

}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!