2012-05-20 1 views
9

जावा में एक छवि से सफेद सीमा को फसल करने का सबसे आसान तरीका क्या है? अग्रिम धन्यवाद ...जावा में एक छवि सफेद सीमा को स्वचालित रूप से कैसे फसल करें?

+1

इस प्रयास करें http://stackoverflow.com/questions/273530/java-image-library-to-deskew- नहीं होगा और-फसल-छवियों – blitzen

उत्तर

5

आप सफेद भागों अदृश्य हो चाहते हैं, सबसे अच्छा तरीका है छवि फिल्टर का उपयोग और सफेद पिक्सेल को पारदर्शी बनाने के लिए, यह @PhiLho द्वारा discussed here है कुछ अच्छे नमूने के साथ, यदि आप आकार बदलने के लिए चाहते हैं आपकी छवि इसलिए इसकी सीमाओं में सफेद रंग नहीं होंगे, आप इसे चार साधारण लूप, के साथ कर सकते हैं, इस छोटे से विधि के लिए मैंने लिखा है कि यह चाल है, यह ध्यान दें कि यह छवि के ऊपरी भाग को फसल करता है, आप लिख सकते हैं बाकी,

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

यहाँ सभी 4 पक्षों फसल के लिए एक रास्ता है, आधार रेखा के रूप बहुत शीर्ष बाएँ पिक्सेल से रंग का उपयोग, और रंग भिन्नता के एक सहिष्णुता इतना im में है कि शोर के लिए अनुमति उम्र फसल बेकार

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

बिल्कुल सही! बहुत बहुत धन्यवाद! – mbelow

+0

इस टोलेंस का अर्थ क्या है? –

+0

सहिष्णुता अभी भी पूरी तरह से ठोस पृष्ठभूमि रंग के बिना छवियों के लिए अनुमति देता है। उदाहरण के लिए, यदि आप पेपर की शीट से ड्रॉइंग स्कैन करते हैं, तो पेपर एक सटीक सफेद के रूप में दिखाई नहीं देगा, बल्कि सफेद रंग के करीब रंगों की एक श्रृंखला होगी। यदि आपने केवल सफेद रंग के एक विशिष्ट रंग से मिलान करके फसल लगाने की कोशिश की, तो थोड़ा (यदि कुछ भी) फसल हो जाए। पृष्ठभूमि के रंग में कुछ भिन्नता की अनुमति देकर, यह सभी अनावश्यक पृष्ठभूमि को हटा सकता है और आपको केवल चित्र के साथ छोड़ देता है। – Todd

0

और यहाँ सिर्फ एक और उदाहरण

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