मैं जावा का उपयोग करके छवि का आकार कैसे बदल सकता हूं?


126

मुझे PNG, JPEG और GIF फ़ाइलों का आकार बदलने की आवश्यकता है। मैं जावा का उपयोग करके यह कैसे कर सकता हूं?


14
जब से आपने लाइब्रेरी के लिए पूछा है, असली जवाब यहाँ है: stackoverflow.com/questions/244164/… । स्वीकार किए गए उत्तर में कोड की तुलना में इसका उपयोग करना बहुत आसान है;)
आर्टूर गजोय

मैं पुस्तकालय के भाग से असहमत हूँ: Graphics2D awt पुस्तकालय का हिस्सा है और यह खुला स्रोत है। पिछले भाग (ओपन सोर्स) के लिए, मैं 100% निश्चित नहीं हूं, लेकिन फिर भी awt कोड को कौन देखेगा?
Burkhard

जवाबों:


87

छवि लोड करने के बाद आप कोशिश कर सकते हैं:

BufferedImage createResizedCopy(Image originalImage, 
            int scaledWidth, int scaledHeight, 
            boolean preserveAlpha)
    {
        System.out.println("resizing...");
        int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
        Graphics2D g = scaledBI.createGraphics();
        if (preserveAlpha) {
            g.setComposite(AlphaComposite.Src);
        }
        g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null); 
        g.dispose();
        return scaledBI;
    }

9
मैंने पाया कि यह तकनीक एक छवि बनाती है जो मेरी जरूरतों के लिए उच्च-गुणवत्ता वाली नहीं है।
मोर्गनकोड्स 21

1
क्या Image.getScaledInstance (चौड़ाई, ऊंचाई, संकेत) भी करेगा?
कोडप्ले

1
क्या preserveAlpha (ImageType के लिए) गलत तरीके से जाँच कर रहा है?
थिलो

मैं @morgancodes से सहमत हूं। समान आयामों का आकार बदलने पर OS X पूर्वावलोकन के साथ आपके द्वारा प्राप्त की गई छवि की गुणवत्ता बहुत खराब है। कुछ ओपन-सोर्स लाइब्रेरी को देखने की कोशिश करेंगे कि क्या वे बेहतर किराया देते हैं।
थिलो

1
"कुछ ओपन-सोर्स लाइब्रेरीज़ को देखने की कोशिश करेंगे कि क्या वे बेहतर किराया देते हैं।" @ RiyadKalla के उत्तर से imgscalr के लिए +1।
थिलो

182

FWIW I ने अभी जारी किया (Apache 2, GitHub पर होस्ट किया गया) जावा के लिए एक साधारण इमेज-स्केलिंग लाइब्रेरी जिसे imgscalr कहा जाता है ( मावेन केंद्रीय पर उपलब्ध )।

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

उपयोग मृत-सरल है, बस स्थैतिक तरीकों का एक गुच्छा है। सबसे सरल उपयोग-मामला है:

BufferedImage scaledImage = Scalr.resize(myImage, 200);

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

मुझे पता है कि यह आत्म-प्रचार की तरह दिखता है (यह है), लेकिन मैंने अपना उचित समय इस सटीक विषय पर गुगली में बिताया और विभिन्न परिणामों / दृष्टिकोणों / विचारों / सुझावों के साथ आता रहा और बैठकर लिखने का फैसला किया सरल कार्यान्वयन जो कि 80-85% उपयोग-मामलों को संबोधित करेगा, जहां आपकी एक छवि है और शायद इसके लिए एक थंबनेल चाहते हैं - या तो जितनी जल्दी हो सके या जितना संभव हो उतना अच्छा दिखने वाले (उन लोगों के लिए, जिन्होंने कोशिश की है, आप देखेंगे। एक छोटी सी पर्याप्त छवि के लिए BICUBIC प्रक्षेप के साथ भी Graphics.drawImage करना, यह अभी भी कचरा जैसा दिखता है)।


1
रियाद, मुझे स्कैलर का उपयोग करना पसंद था। मुझे यह जानने की उत्सुकता है कि आपने सभी स्टैटिक विधियों के साथ एक एपीआई चुनना कैसे समाप्त किया? मैंने एक समान एपी लिखा था जो एक बिल्डर के करीब था। की तरह new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()। मुझे आपका तरीका भी पसंद है और मुझे लगता है कि यह सरल है।
अमीर रामिनफर

4
आमिर, बिल्डर पैटर्न साथ ही पुस्तकालयों के इन प्रकार के लिए शानदार काम करता है, मैं सिर्फ इसलिए मैंने सोचा कि यह एक था स्थिर-विधि दृष्टिकोण के साथ जाने के लिए हुआ बाल आसान नए उपयोगकर्ताओं और उपयोग पैटर्न मैं imgscalr से उम्मीद के लिए पालन करने के लिए (मूल रूप से केवल एकल आकार के तरीकों) को राज्य धारण करने वाले उदाहरण (बिल्डर उदाहरण) से लाभ नहीं मिला। इसलिए मैंने ऑब्जेक्ट इंस्टेंटेशन पर सेव किया और स्टैटिक तरीकों से गया। मैंने हर उस जगह पर imgscalr के अंदर वस्तु-निर्माण के खिलाफ एक मजबूत रुख अपनाया है जहाँ मैं इससे बच सकता हूँ। दोनों दृष्टिकोण हालांकि महान काम करते हैं।
रियाद कल्ला

5
केंद्रीय मावेन भंडार पर इसे उपलब्ध कराने के लिए +1!
ग्रिल्स

यह बफर्डमैज क्लास क्या है, एंड्रॉइड स्टूडियो इसे क्यों नहीं ढूंढता? @ रियाद कल्ला
मिलाद

3
@ xe4me BufferedImage J2SE JDK (Java2D फ्रेमवर्क का हिस्सा) में एक वर्ग है जिसका उपयोग कच्चे, असम्पीडित पिक्सेल डेटा का प्रतिनिधित्व करने के लिए किया जाता है। यह एंड्रॉइड पर उपलब्ध नहीं है, एंड्रॉइड छवि डेटा के साथ काम करने के लिए अपनी कक्षाएं प्रदान करता है।
रियाद कल्ला

54

थंबनेल एक ओपन-सोर्स छवि है जो एमआईटी लाइसेंस के तहत वितरित एक धाराप्रवाह इंटरफ़ेस के साथ जावा के लिए लाइब्रेरी का आकार देता है

मैंने इस लाइब्रेरी को लिखा क्योंकि जावा में उच्च-गुणवत्ता वाले थंबनेल बनाना आश्चर्यजनक रूप से कठिन हो सकता है, और परिणामस्वरूप कोड बहुत गड़बड़ हो सकता है। थंबनेल के साथ, एक सरल धाराप्रवाह एपीआई का उपयोग करके काफी जटिल कार्यों को व्यक्त करना संभव है।

एक सरल उदाहरण

एक साधारण उदाहरण के लिए, एक चित्र लेना और इसे 100 x 100 में बदलना (मूल छवि के पहलू अनुपात को संरक्षित करना), और इसे एक फ़ाइल में सहेजना एक एकल विवरण में प्राप्त किया जा सकता है:

Thumbnails.of("path/to/image")
    .size(100, 100)
    .toFile("path/to/thumbnail");

एक उन्नत उदाहरण

Thumbnailator के धाराप्रवाह इंटरफ़ेस के साथ जटिल आकार देने वाले कार्यों का निष्पादन सरल है।

मान लें कि हम निम्नलिखित कार्य करना चाहते हैं:

  1. एक निर्देशिका में छवियों को ले लो और
  2. मूल छवि के पहलू अनुपात के साथ उन्हें 100 x 100 का आकार दें,
  3. उन सभी को JPEG में सहेजें 0.85, जिनकी गुणवत्ता सेटिंग के साथ ,
  4. जहाँ फ़ाइल नाम मूल thumbnail.से शुरू में संलग्न है

Thumbnailator में अनुवादित, हम निम्नलिखित के साथ उपरोक्त प्रदर्शन करने में सक्षम होंगे:

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(100, 100)
    .outputFormat("JPEG")
    .outputQuality(0.85)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

छवि गुणवत्ता और गति के बारे में एक नोट

यह लाइब्रेरी स्वीकार्य रनटाइम प्रदर्शन सुनिश्चित करते हुए उच्च-गुणवत्ता वाले थंबनेल उत्पन्न करने के लिए चेट हासे और रोमेन गाइ द्वारा गंदी रिच ग्राहकों में उजागर प्रगतिशील बिलिनियर स्केलिंग पद्धति का उपयोग करती है ।


1
coobird, एपीआई के साथ वास्तव में अच्छा काम। बहुत सीधे आगे और प्रयोग करने में आसान।
रियाद कल्ला

@ लॉर्ड्स: मुझे खुशी है कि आपने पाया कि थंबनेल का उपयोग करना आसान है :)
कॉयबर्ड

मैं 500x400 मूल छवि के साथ 80x80 थंबनेल कैसे बना सकता हूं? मैंने इसके लिए कोई विकल्प नहीं देखा। धन्यवाद!
टेरी

".outputFormat (" JPEG ") दस्तावेज़ में कहीं नहीं लिखा है।
विंसेंट कैंटिन

तरीकों जो इस्तेमाल किया जा सकता की पूरी सूची @Vincent Thumbnailator API दस्तावेज़ में है - thumbnailator.googlecode.com/hg/javadoc/net/coobird/...
coobird

12

ऐसा करने के लिए आपको किसी लाइब्रेरी की आवश्यकता नहीं है। आप इसे जावा के साथ ही कर सकते हैं।

क्रिस कैम्पबेल ने स्केलिंग छवियों पर एक उत्कृष्ट और विस्तृत लेखन किया है - इस लेख को देखें

चेत हासे और रोमैन गाइ ने अपनी पुस्तक, गंदी रिच क्लाइंट्स में छवि स्केलिंग का एक विस्तृत और बहुत जानकारीपूर्ण लेखन किया है ।


7
क्रिस का लेख ठीक उसी तरह है जिसने मुझे पहली बार में इमगस्कल लिखने के लिए प्रेरित किया; और इस तरह के सवाल (और आपके जैसे जवाब)। बहुत से लोग बार-बार पूछते हैं कि एक छवि से अच्छे दिखने वाले थंबनेल कैसे प्राप्त करें। इसे करने के कई तरीके हैं, क्रिस हमेशा सबसे अच्छा तरीका नहीं है, यह इस बात पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं और कमी कितनी बड़ी है। imgscalr उस सभी को संबोधित करता है और यह 1 वर्ग है।
रियाद कल्ला

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


9

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

मेरा सुझाव है कि यदि आप इसके साथ भाग सकते हैं, तो ImageMagick को एक बाहरी निष्पादन योग्य के रूप में उपयोग करें। इसका उपयोग करने के लिए सरल है और यह काम ठीक करता है ताकि आपको नहीं करना पड़े।


4

यदि, आपकी मच्छी पर इमेजमागिक स्थापित होना एक विकल्प है, तो मैं im4java की सलाह देता हूं । यह कमांड लाइन इंटरफेस पर एक बहुत पतली अमूर्त परत है, लेकिन यह अपना काम बहुत अच्छी तरह से करता है।


3

जावा एपीआई इमेज और डाउनग्रेडिंग इमेज क्वालिटी के लिए एक मानक स्केलिंग सुविधा प्रदान नहीं करता है।

इस वजह से मैंने JavaCV से cvResize का उपयोग करने की कोशिश की, लेकिन यह समस्या पैदा करता है।

मुझे छवि स्केलिंग के लिए एक अच्छी लाइब्रेरी मिली: बस अपने pom.xml में "जावा-इमेज-स्केलिंग" के लिए निर्भरता जोड़ें।

<dependency>
    <groupId>com.mortennobel</groupId>
    <artifactId>java-image-scaling</artifactId>
    <version>0.8.6</version>
</dependency>

मावेन रिपॉजिटरी में आपको इसके लिए हालिया संस्करण मिलेगा।

पूर्व। अपने जावा कार्यक्रम में

ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);

यह GitHub ( github.com/mortennobel/java-image-scaling.git ) पर भी उपलब्ध है और इसका अब तक का संस्करण 8.7 है। इसे pom.xml में li'l फिक्स की आवश्यकता थी, आप (बदलते स्रोत और लक्ष्य कम से कम 1.6 के रूप में नए मैवेन 1.5% का समर्थन नहीं करते हैं)।
क्रॉम्पायर

2

आप Java के लिए कॉमैंड -लाइन इंटरफ़ेस के रूप में im4java के साथ GraphicsMagick इमेज प्रोसेसिंग सिस्टम का उपयोग करने का प्रयास कर सकते हैं ।

GraphicsMagick के बहुत सारे फायदे हैं, लेकिन सभी के लिए एक:

  • जीएम का उपयोग दुनिया की सबसे बड़ी फोटो साइटों (जैसे फ़्लिकर और एटसी) पर अरबों फाइलों को संसाधित करने के लिए किया जाता है।

1

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

http://www.jmagick.org/index.html


1

बस बर्कहार्ड के उत्तर का उपयोग करें लेकिन ग्राफिक्स बनाने के बाद इस लाइन को जोड़ें:

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

आप मूल्य को BICUBIC में भी सेट कर सकते हैं, यह एक बेहतर गुणवत्ता वाली छवि का उत्पादन करेगा लेकिन एक अधिक महंगा ऑपरेशन है। अन्य रेंडरिंग संकेत हैं जो आप सेट कर सकते हैं लेकिन मैंने पाया है कि प्रक्षेप सबसे उल्लेखनीय प्रभाव पैदा करता है। ध्यान रखें यदि आप बहुत अधिक ज़ूम करना चाहते हैं, तो जावा कोड सबसे अधिक संभावना है, बहुत धीमा होगा। मुझे लगता है कि बड़ी छवियां लगभग 300% ज़ूम का उत्पादन करना शुरू कर देती हैं, यहां तक ​​कि सभी रेंडरिंग संकेत भी गुणवत्ता पर गति के लिए अनुकूलन करने के लिए सेट होते हैं।



1

यह पता चला है कि एक प्रदर्शनशील स्केलर लिखना तुच्छ नहीं है। मैंने इसे एक बार ओपन सोर्स प्रोजेक्ट के लिए किया था: ImageScaler

सिद्धांत रूप में 'java.awt.Image # getScaledInstance (int, int, int)' काम भी करेगा, लेकिन इसके साथ एक बुरा बग भी है - विवरण के लिए मेरे लिंक का संदर्भ लें।


0

मैंने जीआईएफ एनीमेशन से निपटने के लिए उपलब्ध स्वतंत्र रूप से उपलब्ध कक्षाओं (एनीमेटेडगैफ एंकोडर, गिफडेकोडर और एलडब्ल्यूजेनकोडर) के साथ एक समाधान विकसित किया है।
आप jgifcode जार डाउनलोड कर सकते हैं और GifImageUtil क्लास चला सकते हैं। लिंक: http://www.jgifcode.com


1
कृपया उत्तर में उल्लेख करें कि क्या आप अपने सुझाए गए उत्पाद से संबद्ध हैं।
हंस ऑल्सन

waw ... कि GIF एनिमेटेड छवि के आकार बदलने के लिए है? और यह मुफ़्त है ?? Wwaww ... मैं इसे अब पर कोशिश करनी चाहिए ...
gumuruh

हाँ यह मेरे द्वारा विकसित किया गया है। यहाँ इसके लिए स्रोत कोड है github.com/rt29/jgifcode - यह अब यहाँ है। मैं अब इसका समर्थन नहीं कर रहा हूं।
रोहित तिवारी


0

तुम न आयात करना चाहते हैं imgScalr @Riyad कल्ला जवाब जो ऊपर मैं परीक्षण किया की तरह भी काम करता है ठीक, तो आप इस से लिया क्या कर सकते हैं पीटर Walser जवाब एक और मुद्दा है, हालांकि पर @Peter Walser:

 /**
     * utility method to get an icon from the resources of this class
     * @param name the name of the icon
     * @return the icon, or null if the icon wasn't found.
     */
    public Icon getIcon(String name) {
        Icon icon = null;
        URL url = null;
        ImageIcon imgicon = null;
        BufferedImage scaledImage = null;
        try {
            url = getClass().getResource(name);

            icon = new ImageIcon(url);
            if (icon == null) {
                System.out.println("Couldn't find " + url);
            }

            BufferedImage bi = new BufferedImage(
                    icon.getIconWidth(),
                    icon.getIconHeight(),
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = bi.createGraphics();
            // paint the Icon to the BufferedImage.
            icon.paintIcon(null, g, 0,0);
            g.dispose();

            bi = resizeImage(bi,30,30);
            scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
            imgicon = new ImageIcon(scaledImage);

        } catch (Exception e) {
            System.out.println("Couldn't find " + getClass().getName() + "/" + name);
            e.printStackTrace();
        }
        return imgicon;
    }

 public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
        float scaleX = (float) areaWidth / image.getWidth();
        float scaleY = (float) areaHeight / image.getHeight();
        float scale = Math.min(scaleX, scaleY);
        int w = Math.round(image.getWidth() * scale);
        int h = Math.round(image.getHeight() * scale);

        int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        boolean scaleDown = scale < 1;

        if (scaleDown) {
            // multi-pass bilinear div 2
            int currentW = image.getWidth();
            int currentH = image.getHeight();
            BufferedImage resized = image;
            while (currentW > w || currentH > h) {
                currentW = Math.max(w, currentW / 2);
                currentH = Math.max(h, currentH / 2);

                BufferedImage temp = new BufferedImage(currentW, currentH, type);
                Graphics2D g2 = temp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2.drawImage(resized, 0, 0, currentW, currentH, null);
                g2.dispose();
                resized = temp;
            }
            return resized;
        } else {
            Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;

            BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = resized.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(image, 0, 0, w, h, null);
            g2.dispose();
            return resized;
        }
    }

0

इस फलने की विधि का प्रयास करें:

ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.