2012-05-20 40 views

Trả lời

5

Nếu bạn muốn các phần màu trắng ẩn, cách tốt nhất là sử dụng bộ lọc ảnh và làm cho các pixel trắng trong suốt, nó là discussed here bởi @PhiLho với một số mẫu tốt, nếu bạn muốn thay đổi kích thước hình ảnh của bạn nên đường viền của nó sẽ không có màu trắng, bạn có thể làm điều đó với bốn vòng đơn giản, phương pháp nhỏ này mà tôi đã viết cho bạn, hãy lưu ý rằng nó chỉ cắt phần trên của hình ảnh, bạn có thể viết nghỉ ngơi,

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

đây là một cách để cắt tất cả 4 phía, bằng cách sử dụng màu sắc từ các điểm ảnh trên cùng bên trái làm cơ sở, và cho phép dung sai của biến đổi màu sắc để tiếng ồn trong im tuổi sẽ không làm cho cây trồng vô dụng

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

Hoàn hảo! Cảm ơn rất nhiều! – mbelow

+0

dung sai này có nghĩa là gì? –

+0

Dung sai cho phép hình ảnh không có màu nền hoàn toàn chắc chắn vẫn bị cắt. Ví dụ: nếu bạn quét một bản vẽ từ một tờ giấy, giấy sẽ không hiển thị dưới dạng màu trắng chính xác, nhưng thay vào đó sẽ bao gồm một dải màu gần màu trắng. Nếu bạn cố gắng cắt chỉ bằng cách kết hợp một màu cụ thể của màu trắng, ít (nếu có) sẽ bị cắt. Bằng cách cho phép một số biến thể về màu sắc của nền bị cắt, nó có thể loại bỏ tất cả các nền xung quanh không cần thiết và để lại cho bạn chỉ với bản vẽ. – Todd

0

Và đây chỉ là một ví dụ

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); 
} 
Các vấn đề liên quan