Hi shakah and Knute,
thanks for your hints. It works, but as I have quite big Images with
lots of white space, it takes a long time to calculate all rows.
But I found another much quicker way (at least for my purpose) - see
code excerpt below.
Glad that you found something that works for you. Performance diff
could be due to reading the image via the BufferedImage class (maybe
just one actual read?) and/or to narrowing down the problem domain to
PNG files (?).
FWIW, I did play with this a bit after my post yesterday to add column-
based cropping and to read the image in all at once (when I noticed
that PixelGrabber's column-by-column reading was particularly slow). I
ended up with the following code that computed the crop rectangle,
which seemed to work OK when passed into ImageMagick's convert/crop
utility:
jc@jc-ubuntu:~/tmp/bgcrop$ cat bgcrop.java
public class bgcrop {
public static void main(String [] args)
throws Exception {
System.exit(new bgcrop().process(args)) ;
}
private static boolean isWhite(int pixel) {
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel ) & 0xff;
return (0xFF==red && 0xFF==green && 0xFF==blue) ;
}
private static boolean areAllWhite(int [] pixels, int off, int len)
{
for(int pixel=off; pixel<off+len; ++pixel) {
if(!isWhite(pixels[pixel])) {
return false ;
}
}
return true ;
}
private static boolean isColumnAllWhite(int [] pixels, int col, int
row_len, int row_offset, int rows) {
for(int row=row_offset; row<row_offset+rows; ++row) {
int pixel=row*row_len+col ;
if(!isWhite(pixels[pixel])) {
return false ;
}
}
return true ;
}
private int process(String [] args)
throws Exception {
int exit_code = 0 ;
for(int arg=0; arg<args.length; ++arg) {
System.out.println("\n" + args[arg]) ;
javax.swing.ImageIcon ii = new
javax.swing.ImageIcon(args[arg]) ;
java.awt.Image img = ii.getImage() ;
System.out.println(" img width: " + ii.getIconWidth()) ;
System.out.println(" img height: " + ii.getIconHeight()) ;
int min_nw_row = -1 ;
int max_nw_row = -1 ;
int [] img_pixels = new int[ii.getIconHeight() *
ii.getIconWidth()] ;
// ...grab this images's pixels
java.awt.image.PixelGrabber pg
= new java.awt.image.PixelGrabber(
img, 0, 0, ii.getIconWidth()
,ii.getIconHeight(), img_pixels, 0, ii.getIconWidth()) ;
pg.grabPixels() ;
for(int row=0; row<ii.getIconHeight(); ++row) {
if(!areAllWhite(img_pixels, ii.getIconWidth()*row,
ii.getIconWidth())) {
if(min_nw_row < 0) {
min_nw_row = row ;
}
else if(row > max_nw_row) {
max_nw_row = row ;
}
}
}
// ...how about column-based cropping?
int min_nw_col = -1 ;
int max_nw_col = -1 ;
for(int col=0; col<ii.getIconWidth(); ++col) {
if(!isColumnAllWhite(img_pixels, col, ii.getIconWidth(),
min_nw_row, max_nw_row-min_nw_row)) {
if(min_nw_col < 0) {
min_nw_col = col ;
}
else if(col > max_nw_col) {
max_nw_col = col ;
}
}
}
System.out.println(" crop rect: (" + min_nw_col + "," +
min_nw_row + ") to (" + max_nw_col + "," + max_nw_row + ")") ;
}
return exit_code ;
}
}