Original Post
Hey I have a fairly silly question to ask. I was doing some low level image manipulation with a memory image source, using an array of pixels to create the image.
My problem is this, when I create an image where the width == height, the formula I use to traverse the array works fine. But when I create an image where the width != height, the way I traverse te array seems to go to hell.
Here is the formula I am using:
int pos = y*this.width + x;
I worked it out on paper and this seems to work just fine for any size array(square or rectangular). But in practice it doesn''t. I am not sure if it is my formula or the memoryImageSource.
Here is the code that I am using. Any hlep would be appreciated.
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{
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[i] = 0xFF000000;
}
this.memSrc = new MemoryImageSource(this.width, this.height, this.source, 0, this.height);
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[i];
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[i] = 0xFF000000|r2|g2|b2;
}
}
public void printFilter(){
for(int i =0; i < 10; i++){
System.out.println("filter[" + i + "]=" + filter[i]);
}
}
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();
}
}