import java.io.*; import java.net.*; import java.awt.*; import java.awt.image.*; import javax.imageio.*; //traverses an master image which is made up of smaller images and //splits them into separate images by comparing color variation across a row or column of pixels //once it finds a split it recursive calls the opposing search //(ie if horizontal split found, image is split and each image is passed to search for vertical split.) //If no split is found the image is saved. //could add a min size test at save if required. public class ImageSplitter extends Component { //fine tune these 3 settings int th1 = 100; int th2 = 100; double th3 = 0.30; //--------------------------- private static BufferedImage srcimg; //test image static String imageFileName = "hmm002.jpg"; static String saveLocation = "output3/img"; int srcw, srch; int saveCounter=1; int splitCounter=1; boolean debugON = true; int debugRow = 999912954;//selects specific row for debug output if reqd public void paint(Graphics g) { g.drawImage(srcimg, 0, 0, null); } public ImageSplitter(URL imageSrc) { try { srcimg = ImageIO.read(imageSrc); srcw = srcimg.getWidth(null); srch = srcimg.getHeight(null); } catch (IOException e) { System.out.println("Image could not be read"); // System.exit(1); } } public Dimension getSize() { if (srcimg == null) { return new Dimension(100,100); } else { return new Dimension(srcw, srch); } } public void saveImage(BufferedImage img2) { try { File outputfile = new File(saveLocation + saveCounter + ".jpg"); ImageIO.write(img2, "jpg", outputfile); System.out.println("Saved "+ saveCounter); } catch (IOException e) { System.out.println("Image could not be saved"); System.exit(1); } } //identify one image above another (horizontal split) public void traverseImageY(BufferedImage img2) { int imageTop = 0; boolean split=false; int w,h; w = img2.getWidth(null); h = img2.getHeight(null); for (int y = 1; y < h-1; y++) { int rowDiff=0; for (int x = 1; x < w-1; x++) { if(debugON && y==debugRow) {System.out.println("X:" + x + " Y:" + y);} int totalDiff = 0; //look at surrounding cells. A horizontal line is where D is different to U,L,C and R across most cells in a row. //for each cell C: check if D > th2 (threshold) "AND" U,L and R are < th1 //increase rowDiff for each cell that meets this criteria. //if enough cells in the row meet this criteria then it is considered a split (rowdiff > th3*w (ie more then th3%) // U // | // L-C-R // | // (D) int clrC = img2.getRGB(x, y); int clrU = img2.getRGB(x, y-1); int clrD = img2.getRGB(x, y+1); int clrL = img2.getRGB(x-1, y); int clrR = img2.getRGB(x+1, y); //diff rows int Cr = (clrC & 0x00ff0000) >> 16; int Cg = (clrC & 0x0000ff00) >> 8; int Cb = clrC & 0x000000ff; //check C to U int Ur = (clrU & 0x00ff0000) >> 16; int Ug = (clrU & 0x0000ff00) >> 8; int Ub = clrU & 0x000000ff; int Udifr=Math.abs(Cr-Ur); int Udifg=Math.abs(Cg-Ug); int Udifb=Math.abs(Cb-Ub); int UDiff=Udifr+Udifg+Udifb; if (UDiff> 16; int Dg = (clrD & 0x0000ff00) >> 8; int Db = clrD & 0x000000ff; int Ddifr=Math.abs(Cr-Dr); int Ddifg=Math.abs(Cg-Dg); int Ddifb=Math.abs(Cb-Db); int DDiff=Ddifr+Ddifg+Ddifb; if (DDiff>th2) {totalDiff++;} //look for > as positive find if(debugON && y==debugRow) {System.out.println("DDiff" + DDiff);} //check C to L int Lr = (clrL & 0x00ff0000) >> 16; int Lg = (clrL & 0x0000ff00) >> 8; int Lb = clrL & 0x000000ff; int Ldifr=Math.abs(Cr-Lr); int Ldifg=Math.abs(Cg-Lg); int Ldifb=Math.abs(Cb-Lb); int LDiff=Ldifr+Ldifg+Ldifb; if (LDiff> 16; int Rg = (clrR & 0x0000ff00) >> 8; int Rb = clrR & 0x000000ff; int Rdifr=Math.abs(Cr-Rr); int Rdifg=Math.abs(Cg-Rg); int Rdifb=Math.abs(Cb-Rb); int RDiff=Rdifr+Rdifg+Rdifb; if (RDiff(th3*w)) { if(debugON) {System.out.println("SPLIT-H" + splitCounter + ": imageTop:" + imageTop + " Y:" + y + " rowDiff:" + rowDiff);} if(y-imageTop>0) { //check for zero size image BufferedImage dest = img2.getSubimage(0, imageTop, w, y-imageTop); splitCounter++; traverseImageX(dest); //traverse top half of split image recursivly split=true; imageTop=y+1; //set marker for bottom half of image } } } ////traverse remaining bottom half of split image recursivly if(split ) { if(debugON) {System.out.println("SPLIT-H" + splitCounter + ": imageTop:" + imageTop + " Y:" + h);} if(h-imageTop>0) { BufferedImage dest = img2.getSubimage(0, imageTop, w, h-imageTop); splitCounter++; traverseImageX(dest); } } else { saveImage(img2); saveCounter++; } } //identify one image next to another (vertical split) public void traverseImageX(BufferedImage img2) { int imageLeft = 0; boolean split=false; int w,h; w = img2.getWidth(null); h = img2.getHeight(null); for (int x = 1; x < w-1; x++) { int colDiff=0; for (int y = 1; y < h-1; y++) { if(debugON && y==debugRow) {System.out.println("X:" + x + " Y:" + y);} int totalDiff = 0; // U // | // L-C-(R) // | // D int clrC = img2.getRGB(x, y); int clrU = img2.getRGB(x, y-1); int clrD = img2.getRGB(x, y+1); int clrL = img2.getRGB(x-1, y); int clrR = img2.getRGB(x+1, y); //diff rows int Cr = (clrC & 0x00ff0000) >> 16; int Cg = (clrC & 0x0000ff00) >> 8; int Cb = clrC & 0x000000ff; int Ur = (clrU & 0x00ff0000) >> 16; int Ug = (clrU & 0x0000ff00) >> 8; int Ub = clrU & 0x000000ff; int Udifr=Math.abs(Cr-Ur); int Udifg=Math.abs(Cg-Ug); int Udifb=Math.abs(Cb-Ub); int UDiff=Udifr+Udifg+Udifb; if (UDiff> 16; int Dg = (clrD & 0x0000ff00) >> 8; int Db = clrD & 0x000000ff; int Ddifr=Math.abs(Cr-Dr); int Ddifg=Math.abs(Cg-Dg); int Ddifb=Math.abs(Cb-Db); int DDiff=Ddifr+Ddifg+Ddifb; if (DDiff> 16; int Lg = (clrL & 0x0000ff00) >> 8; int Lb = clrL & 0x000000ff; int Ldifr=Math.abs(Cr-Lr); int Ldifg=Math.abs(Cg-Lg); int Ldifb=Math.abs(Cb-Lb); int LDiff=Ldifr+Ldifg+Ldifb; if (LDiff> 16; int Rg = (clrR & 0x0000ff00) >> 8; int Rb = clrR & 0x000000ff; int Rdifr=Math.abs(Cr-Rr); int Rdifg=Math.abs(Cg-Rg); int Rdifb=Math.abs(Cb-Rb); int RDiff=Rdifr+Rdifg+Rdifb; if (RDiff>th2) {totalDiff++;} if(debugON && y==debugRow) {System.out.println("RDiff" + RDiff);} if(totalDiff==4) {colDiff++;} if(debugON && y==debugRow) {System.out.println("X:" + x + " Y:" + y +" totalDiff:" + totalDiff + " colDiff:" + colDiff);} } if(colDiff>(th3*h)) { if(debugON) {System.out.println("SPLIT-V" + splitCounter + ": imageLeft:" + imageLeft + " X:" + x + " colDiff:" + colDiff);} if(x-imageLeft>0) { BufferedImage dest = img2.getSubimage(imageLeft, 0, x-imageLeft, h); splitCounter++; traverseImageY(dest); split=true; imageLeft=x+1; } } } if(split) { if(debugON) {System.out.println("SPLIT-V" + splitCounter + ": imageLeft:" + imageLeft + " X:" + w);} if(w-imageLeft>0) { BufferedImage dest = img2.getSubimage(imageLeft, 0, w-imageLeft, h); splitCounter++; traverseImageY(dest); } } else { saveImage(img2); saveCounter++; } } public static void main(String s[]) { URL imageSrc = null; try { imageSrc = ((new File(imageFileName)).toURI()).toURL(); } catch (MalformedURLException e) { } ImageSplitter imgSpl = new ImageSplitter(imageSrc); imgSpl.traverseImageY(srcimg); System.out.println("Compelte"); } }