Reputation: 781
I'm trying to copy colors from a BufferedImage to another bufferedImage, and below is my code. I know that I can use a graphics.drawImage, but I need to change certain colors and that is why I'm copying colors pixel by pixel instead of just painting the image over another BufferedImage It doesn't work though. the line "t.setRGB" doesn't seem to have any affect on the BufferedImage "t" After saving the image "t", I get a blank image. What did I do wrong?
One more question. How can I modify the "myColor" method to use a "alpha" value as well?
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
public class imgSt{
public static int rgb;
public static int myColor( int r, int g, int b){
rgb= (65536 * r) + (256 * g) + (b);
return rgb;
}
public static void main( String args[] ){
try {
BufferedImage img = ImageIO.read(new File( "8.jpg"));
BufferedImage t= new BufferedImage( img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB );
int clear=0x000000FF;
int color, alpha, r, g, b;
for(int i=0; i<img.getWidth(); ++i){
for( int j=0; j<img.getHeight(); ++j ){
color = img.getRGB(i,j);
alpha = (color>>24) & 0xff;
r = (color & 0x00ff0000) >> 16;
g = (color & 0x0000ff00) >> 8;
b = color & 0x000000ff;
t.setRGB( i,j, myColor( r, g, b ) );
}
} //for
ImageIO.write( t, "jpg", new File(" sT.jpg") );
} catch (IOException e){ e.printStackTrace(); }
}//main
}//class
Upvotes: 2
Views: 1219
Reputation: 27113
While using the raster like suggested in the other answers is usually faster than using getRGB()/setRGB()
, there's nothing fundamentally wrong with your approach.
The problem is that the getRGB()/setRGB()
methods work with ARGB values, not just RGB. So when your myColor()
method leaves the alpha component 0, this basically means the color will be 100% transparent. This is why you get a blank image. You probably want 100% opaque pixels instead.
Here's a fixed version of your method (I generally think it's cleaner to stick to bit shifts, so that converting to/from the packed representation is similar) that creates opaque colors in packed ARGB format:
public static int myColor(int r, int g, int b) {
int argb = 0xFF << 24 | r << 16 | g << 8 | b;
return argb;
}
I'd also changed the unpacking code a little for readability, although it's not strictly necessary:
int color = img.getRGB(i,j);
int alpha = (color >>> 24) & 0xff;
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff ;
int b = color & 0xff;
Upvotes: 1
Reputation: 5898
You can do it using the raster:
BufferedImage imsrc = ... // The source image, RGBA
BufferedImage imres = ... // The resulting image, RGB or BGR
WritableRaster wrsrc = imsrc.getRaster() ;
WritableRaster wrres = imres.getRaster() ;
for (int y=0 ; y < image.getHeight() ; y++)
for (int x=0 ; x < image.getWidth() ; x++)
{
wrres.setSample(x, y, 0, wrsrc.getSample(x, y, 0)) ;
wrres.setSample(x, y, 1, wrsrc.getSample(x, y, 1)) ;
wrres.setSample(x, y, 2, wrsrc.getSample(x, y, 2)) ;
}
When using the raster, you don't have to manage the image encoding, the channels are ordered as Red Green Blue Alpha. So I just fo through the entire image, and I copy the RGB pixels into the result.
Upvotes: 0