2012-05-20 31 views

Respuesta

5

Si desea que las partes blancas de ser invisible, la mejor manera es utilizar filtros de imagen y hacer que los píxeles blancos transparente, es discussed here por @PhiLho con algunas buenas muestras, si desea cambiar el tamaño su imagen por lo que sus bordes no tendrán colores blancos, puede hacerlo con cuatro bucles simples, este pequeño método que he escrito para usted hace el truco, tenga en cuenta que solo recorta la parte superior de la imagen, puede escribir el resto,

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

He aquí una manera de recortar los 4 lados, usando el color del píxel muy superior izquierda como línea de base, y permiten una tolerancia de variación de color de modo que el ruido de la im la edad no hará que el cultivo inútil

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

¡Perfecto! ¡Muchas gracias! – mbelow

+0

¿Qué significa esta tolerancia? –

+0

La tolerancia permite que las imágenes sin un color de fondo perfectamente sólido queden recortadas. Por ejemplo, si escanea un dibujo de una hoja de papel, el papel no se mostrará como un blanco exacto, sino que consistirá en un rango de colores cercano al blanco. Si intentaba recortar simplemente haciendo coincidir un color específico de blanco, se recortaría poco (si acaso). Al permitir alguna variación en el color del fondo que se está recortando, puede eliminar todo el fondo circundante innecesario y dejarlo solo con el dibujo. – Todd

0

Y aquí otro ejemplo

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); 
} 
Cuestiones relacionadas