2009-05-03 12 views
12

मेरे पास जावा (स्प्रिंग, हाइबरनेट/जेपीए, स्ट्रूट 2) में लिखा गया एक वेब एप्लिकेशन है जहां उपयोगकर्ता छवियां अपलोड कर सकते हैं और उन्हें फाइल सिस्टम में स्टोर कर सकते हैं। मैं उन छवियों को स्केल करना चाहता हूं ताकि वे साइट पर प्रदर्शित होने के लिए एक सतत आकार के हों। कौन से पुस्तकालय या कार्यों में निर्मित सर्वोत्तम परिणाम प्रदान करेंगे? मैं अपने निर्णय लेने में निम्नलिखित मानदंडों (इस क्रम में) पर विचार करेंगे: लागू करने के लिए जावा में छवियों को स्केल करने का सबसे अच्छा तरीका क्या है?

  • आसान परिणामों की
  • गुणवत्ता

    • नि: शुल्क/खुला स्रोत (आवश्यक)
    • प्रदर्शन
    • का आकार निष्पादन योग्य
  • उत्तर

    4

    छवि को पढ़ने/लिखने के लिए Java Image I/O API पर एक नज़र डालें। फिर आकार बदलने के लिए AffineTransform का उपयोग करें।

    इसके अलावा, here's java.awt.Image का उपयोग करके एक पूर्ण उदाहरण है।

    +0

    आपके द्वारा उद्धृत उदाहरण 'getScaledInstance()' का उपयोग कर रहा है, AffineTransform नहीं। तो यह कौन है? मैंने मिश्रित समीक्षा पढ़ी है कि 'getScaledInstance' निष्पादक के रूप में नहीं है ... – gdbj

    4

    java-image-scaling लाइब्रेरी में भी देखें। यह छवि गुणवत्ता बेहतर छवियों का निर्माण किया।

    0

    छवि संपादन के लिए सबसे अच्छा उपकरण ImageMagick है और यह खुला स्रोत है।

    जावा भाषा के लिए दो इंटरफेस के होते हैं:

    JMagick जो ImageMagick

    और

    im4java क्या ImageMagick

    के लिए एक कमांड लाइन इंटरफेस है JNI इंटरफ़ेस का उपयोग करता
    9

    मैं वास्तव में की सिफारिश करेंगे imgscalr एक नज़र देना।

    यह एक अपाचे 2 लाइसेंस के तहत जारी की है GitHub पर होस्ट, वेब अनुप्रयोगों पहले से ही के एक मुट्ठी भर में तैनात कर दिया, एक बहुत ही सरल है, लेकिन pedantically documented API, कोड है कि पारदर्शी रूप से आप के लिए JDK में लगभग 2 प्रमुख छवि कीड़े काम करता है कि आप कभी भी ध्यान देंगे कि यदि आप स्केल ऑपरेशन या भयानक दिखने वाले परिणामों के बाद अचानक "काला" छवियां प्राप्त करना शुरू करते हैं, तो आपको जावा में उपलब्ध सर्वोत्तम संभव दिखने वाले परिणाम मिलते हैं, मेवेन के साथ-साथ एक ज़िप के माध्यम से भी उपलब्ध है और केवल एक एकल वर्ग

    बुनियादी उपयोग इस तरह दिखता है:

    BufferedImage img = ImageIO.read(...); // load image 
    BufferedImage scaledImg = Scalr.resize(img, 320); 
    

    यह सबसे सरल कॉल जहां पुस्तकालय गुणवत्ता पर एक सबसे लगता है कि कर देगा, अपनी छवि अनुपात का सम्मान, और एक 320x320 बाउंडिंग बॉक्स के भीतर परिणाम फिट है। ध्यान दें, बाउंडिंग बॉक्स केवल अधिकतम डब्ल्यू/एच है, क्योंकि आपकी छवि अनुपात को सम्मानित किया जाता है, परिणामी छवि अभी भी इसका सम्मान करेगी, 320x200 कहें।

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

    BufferedImage img = ImageIO.read(...); // load image 
    BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                 150, 100, Scalr.OP_ANTIALIAS); 
    

    ये सभी उदाहरण हैं, एपीआई व्यापक है और सुपर-सरल उपयोग मामलों से सबकुछ बहुत विशिष्ट है।आप छवि पर लागू होने के लिए अपने स्वयं के BufferedImageOps में भी पास कर सकते हैं (और लाइब्रेरी स्वचालित रूप से आपके लिए 6-वर्षीय BufferedImageOp जेडीके बग को ठीक करता है!)

    जावा में छवियों को स्केल करने के लिए बहुत कुछ है सफलतापूर्वक लाइब्रेरी करता है आपके लिए, उदाहरण के लिए हमेशा छवि को सर्वोत्तम ऑपरेटिंग आरजीबी या एआरजीबी छवि प्रकारों में से एक में रखते हुए इसे चालू करते समय रखें। कवर के तहत जावा 2 डी छवि प्रसंस्करण पाइपलाइन किसी भी छवि संचालन के लिए उपयोग की जाने वाली छवि प्रकार खराब रूप से समर्थित होने पर एक निम्न सॉफ्टवेयर पाइपलाइन पर वापस आती है।

    यदि सभी जो सिरदर्द की तरह लगते हैं, तो यह है ... यही कारण है कि मैंने पुस्तकालय लिखा और इसे खोल दिया, इसलिए लोग अपनी छवियों का आकार बदल सकते थे और बिना किसी चिंता के अपने जीवन के साथ आगे बढ़ सकते थे यह।

    उम्मीद है कि मदद करता है।

    0

    मैंने मानक जावा 1.6 की तुलना में imgscalr की कोशिश की और मैं यह नहीं कह सकता कि यह बेहतर है।

    मैं क्या कोशिश की है

    BufferedImage bufferedScaled = Scalr.resize(sourceImage, Method.QUALITY, 8000, height); 
    

    और

    Image scaled = sourceImage.getScaledInstance(-1, height, Image.SCALE_SMOOTH); 
        BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null), scaled.getHeight(null), BufferedImage.TYPE_INT_RGB); 
        bufferedScaled.getGraphics().drawImage(scaled, 0, 0, null); 
    

    मेरी आंख से कुछ 5 मिनट परीक्षण धारणा है कि दूसरी बात (शुद्ध जावा 1.6) बेहतर परिणाम मिल गया है।

    -1

    इस मिले तेजी से होने के लिए:

    public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, final int targetHeight, 
                   final Object hint) { 
        final int type = BufferedImage.TYPE_INT_RGB; 
        int drawHeight = targetHeight; 
        int drawWidth = targetWidth; 
        final int imageWidth = img.getWidth(); 
        final int imageHeight = img.getHeight(); 
        if ((imageWidth <= targetWidth) && (imageHeight <= targetHeight)) { 
         logger.info("Image " + imageWidth + "/" + imageHeight + " within desired scale"); 
         return img; 
        } 
        final double sar = ((double) imageWidth)/((double) imageHeight); 
        if (sar != 0) { 
         final double tar = ((double) targetWidth)/((double) targetHeight); 
         if ((Math.abs(tar - sar) > .001) && (tar != 0)) { 
          final boolean isSoureWider = sar > (targetWidth/targetHeight); 
          if (isSoureWider) { 
           drawHeight = (int) (targetWidth/sar); 
          } 
          else { 
           drawWidth = (int) (targetHeight * sar); 
          } 
         } 
        } 
        logger.info("Scaling image from " + imageWidth + "/" + imageHeight + " to " + drawWidth + "/" + drawHeight); 
        final BufferedImage result = new BufferedImage(drawWidth, drawHeight, type); 
        try { 
         final Graphics2D g2 = result.createGraphics(); 
         try { 
          if (hint != null) { 
           g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); 
          } 
          g2.drawImage(img, 0, 0, drawWidth, drawHeight, null); 
         } 
         finally { 
          g2.dispose(); 
         } 
         return result; 
        } 
        finally { 
         result.flush(); 
        } 
    } 
    
    1

    मैं जानता हूँ कि यह एक बहुत पुरानी सवाल है, लेकिन मैं इस मानक जावा एपीआई का उपयोग कर के लिए अपने ही समाधान मिल गया

    import java.awt.*; 
    import java.awt.event.*; 
    import javax.imageio.* 
    import java.awt.image.*; 
    
    BufferedImage im, bi, bi2; 
    Graphics2D gfx; 
    int imWidth, imHeight, dstWidth, dstHeight; 
    int DESIRED_WIDTH = 500, DESIRED_HEIGHT = 500; 
    
    im = ImageIO.read(new File(filePath)); 
    imWidth = im.getWidth(null); 
    imHeight = im.getHeight(null); 
    
    dstWidth = DESIRED_WIDTH; 
    dstHeight = (dstWidth * imHeight)/imWidth; 
    
    bi = new BufferedImage(dstWidth, dstHeight, im.getType()); 
    
    gfx = bi.createGraphics(); 
    gfx.drawImage(im, 0, 0, dstWidth, dstHeight, 0, 0, imWidth, imHeight, null); 
    
    bi2 = new BufferedImage(DESIRED_WIDTH, DESIRED_HEIGHT, im.getType()); 
    gfx = bi2.createGraphics(); 
    
    gfx.drawImage(bi, 0, 0, DESIRED_WIDTH, DESIRED_HEIGHT, null); 
    
    ImageIO.write(bi2, "jpg", new File(filePath)); 
    

    मुझे यकीन है यह कर सकते हैं सुधार और अनुकूलित किया जाना चाहिए।

    संबंधित मुद्दे