2012-05-20 11 views

risposta

5

Se si desidera che le parti bianche siano invisibili, il modo migliore è utilizzare i filtri immagine e rendere trasparenti i pixel bianchi, è discussed here di @PhiLho con alcuni buoni esempi, se si desidera ridimensionare la tua immagine in modo che i bordi non abbiano colori bianchi, puoi farlo con quattro semplici loop, questo piccolo metodo che ho scritto per te fa il trucco, nota che ritaglia solo la parte superiore dell'immagine, puoi scrivere il riposo,

private Image getCroppedImage(String address) throws IOException{ 
    BufferedImage source = ImageIO.read(new File(address)) ; 

    boolean flag = false ; 
    int upperBorder = -1 ; 
    do{ 
     upperBorder ++ ; 
     for (int c1 =0 ; c1 < source.getWidth() ; c1++){ 
      if(source.getRGB(c1, upperBorder) != Color.white.getRGB()){ 
       flag = true; 
       break ; 
      } 
     } 

     if (upperBorder >= source.getHeight()) 
      flag = true ; 
    }while(!flag) ; 

    BufferedImage destination = new BufferedImage(source.getWidth(), source.getHeight() - upperBorder, BufferedImage.TYPE_INT_ARGB) ; 
    destination.getGraphics().drawImage(source, 0, upperBorder*-1, null) ; 

    return destination ; 
} 
23

Ecco un modo per ritagliare 4 lati, utilizzando il colore dal pixel molto superiore sinistro come linea di base, e consentire una tolleranza di variazione di colore in modo che il rumore nella im età non farà il raccolto inutile

public BufferedImage getCroppedImage(BufferedImage source, double tolerance) { 
    // Get our top-left pixel color as our "baseline" for cropping 
    int baseColor = source.getRGB(0, 0); 

    int width = source.getWidth(); 
    int height = source.getHeight(); 

    int topY = Integer.MAX_VALUE, topX = Integer.MAX_VALUE; 
    int bottomY = -1, bottomX = -1; 
    for(int y=0; y<height; y++) { 
     for(int x=0; x<width; x++) { 
     if (colorWithinTolerance(baseColor, source.getRGB(x, y), tolerance)) { 
      if (x < topX) topX = x; 
      if (y < topY) topY = y; 
      if (x > bottomX) bottomX = x; 
      if (y > bottomY) bottomY = y; 
     } 
     } 
    } 

    BufferedImage destination = new BufferedImage((bottomX-topX+1), 
       (bottomY-topY+1), BufferedImage.TYPE_INT_ARGB); 

    destination.getGraphics().drawImage(source, 0, 0, 
       destination.getWidth(), destination.getHeight(), 
       topX, topY, bottomX, bottomY, null); 

    return destination; 
} 

private boolean colorWithinTolerance(int a, int b, double tolerance) { 
    int aAlpha = (int)((a & 0xFF000000) >>> 24); // Alpha level 
    int aRed = (int)((a & 0x00FF0000) >>> 16); // Red level 
    int aGreen = (int)((a & 0x0000FF00) >>> 8); // Green level 
    int aBlue = (int)(a & 0x000000FF);   // Blue level 

    int bAlpha = (int)((b & 0xFF000000) >>> 24); // Alpha level 
    int bRed = (int)((b & 0x00FF0000) >>> 16); // Red level 
    int bGreen = (int)((b & 0x0000FF00) >>> 8); // Green level 
    int bBlue = (int)(b & 0x000000FF);   // Blue level 

    double distance = Math.sqrt((aAlpha-bAlpha)*(aAlpha-bAlpha) + 
           (aRed-bRed)*(aRed-bRed) + 
           (aGreen-bGreen)*(aGreen-bGreen) + 
           (aBlue-bBlue)*(aBlue-bBlue)); 

    // 510.0 is the maximum distance between two colors 
    // (0,0,0,0 -> 255,255,255,255) 
    double percentAway = distance/510.0d;  

    return (percentAway > tolerance); 
} 
+0

Perfetto! Grazie mille! – mbelow

+0

cosa significa questa tolleranza? –

+0

La tolleranza consente di ritagliare immagini senza un colore di sfondo perfettamente solido. Ad esempio, se si esegue la scansione di un disegno da un foglio di carta, la carta non verrà visualizzata come un bianco esatto, ma sarà costituita da una gamma di colori vicini al bianco. Se si è tentato di ritagliare semplicemente abbinando un colore specifico di bianco, sarebbe stato ritagliato poco (se non altro). Consentendo la variazione del colore dello sfondo ritagliato, è possibile rimuovere tutto lo sfondo circostante non necessario e lasciare solo il disegno. – Todd

0

E qui solo un altro esempio

private static BufferedImage autoCrop(BufferedImage sourceImage) { 
    int left = 0; 
    int right = 0; 
    int top = 0; 
    int bottom = 0; 
    boolean firstFind = true; 
    for (int x = 0; x < sourceImage.getWidth(); x++) { 
     for (int y = 0; y < sourceImage.getWidth(); y++) { 
      // pixel is not empty 
      if (sourceImage.getRGB(x, y) != 0) { 

       // we walk from left to right, thus x can be applied as left on first finding 
       if (firstFind) { 
        left = x; 
       } 

       // update right on each finding, because x can grow only 
       right = x; 

       // on first find apply y as top 
       if (firstFind) { 
        top = y; 
       } else { 
        // on each further find apply y to top only if a lower has been found 
        top = Math.min(top, y); 
       } 

       // on first find apply y as bottom 
       if (bottom == 0) { 
        bottom = y; 
       } else { 
        // on each further find apply y to bottom only if a higher has been found 
        bottom = Math.max(bottom, y); 
       } 
       firstFind = false; 
      } 
     } 
    } 

    return sourceImage.getSubimage(left, top, right - left, bottom - top); 
} 
Problemi correlati