2012-05-20 10 views

Odpowiedz

5

Jeśli chcesz, aby białe części były niewidoczne, najlepiej użyć filtrów obrazu i uczynić białe piksele przezroczystym, to jest discussed here autorki @PhiLho z kilkoma dobrymi próbkami, , jeśli chcesz zmienić rozmiar twój obrazek, więc jego granice nie będą miały białych kolorów, możesz to zrobić za pomocą czterech prostych pętli, ta mała metoda, którą napisałem dla ciebie, robi sztuczkę, zauważ, że po prostu przycina górną część obrazu, możesz napisać reszta,

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

Oto sposób przyciąć wszystkich 4 stron, z użyciem koloru z bardzo lewego górnego piksela jako linii bazowej, i pozwolić na tolerowanie wariacji kolorów, tak aby hałas w IM wiek nie będzie upraw bezużyteczną

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

Idealne! Dziękuję bardzo! – mbelow

+0

co oznacza ta tolerancja? –

+0

Tolerancja pozwala na przycinanie obrazów bez idealnie jednolitego koloru tła. Na przykład, jeśli zeskanujesz rysunek z kartki papieru, papier nie pojawi się jako biały, ale będzie składał się z zakresu kolorów zbliżonych do białego. Jeśli próbowałeś przyciąć, dopasowując jeden konkretny kolor bieli, małe (jeśli w ogóle) byłyby przycięte. Pozwalając na zmianę koloru przycinanego tła, można usunąć całe niepotrzebne otoczenie i pozostawić tylko rysunek. – Todd

0

I tu właśnie kolejny przykład

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); 
} 
Powiązane problemy