2012-02-22 2 views
5

का उपयोग करके इसे एनीमेशन रखने के दौरान एनिमेटेड जीआईएफ का आकार बदल रहा है, मैं जावा में ग्राफिक्स 2 डी का उपयोग छवियों का आकार बदलने के लिए कर रहा हूं, यह जेपीजी, पीएनजी और अन्य प्रारूपों के साथ सही काम करता है। एनीमेशन फिर से आकार देने के बाद, मेरी समस्या एनिमेटेड जीआईएफ छवियां है!जावा

यहाँ

है विधि का उपयोग कर रहा हूँ:

private BufferedImage doResize(int newWidth, int newHeight, double scaleX, 
     double scaleY, BufferedImage source) { 

    GraphicsConfiguration gc = getDefaultConfiguration(); 
    BufferedImage result = gc.createCompatibleImage(newWidth, newHeight, source.getColorModel().getTransparency()); 
    Graphics2D g2d = null; 

    try { 
     g2d = result.createGraphics(); 
     g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 
     g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
     g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.scale(scaleX, scaleY); 
     g2d.drawImage(source, 0, 0, null); 
    } finally { 
     if (g2d != null) { 
      g2d.dispose(); 
     } 
    } 

    return result; 
} 

हां, तो किसी भी सुराग मैं कैसे ऐनिमेटेड gif पर रख सकते हैं फिर से आकार देने के बाद? धन्यवाद।

उत्तर

4

मुझे दो स्रोत मिले जो एनीमेशन को रखते हुए छवि का आकार बदलने के लिए संयुक्त रूप से उपयोग किए जा सकते हैं।

इस प्रश्न पर ( Convert each animated GIF frame to a separate BufferedImage) Alex Orzechowski द्वारा उत्तर की तलाश करें। उसका कोड एक gif फ़ाइल लेता है और इसे इमेजफ्रेम की एक सरणी में परिवर्तित करता है (जो वह वर्ग है जिसे उसने बुफर्ड इमेज लपेट लिया है)। फिर इस कोड को देखें जो BufferedImages के अनुक्रम को एक gif फ़ाइल (http://elliot.kroo.net/software/java/GifSequenceWriter/) में परिवर्तित करता है।

आप शायद लगता है कि हो सकता है के रूप में, तुम सब करने की जरूरत है GIF अपलोड करें, एलेक्स के कोड का उपयोग, ImageFiles/BufferedImages की एक सरणी के लिए परिवर्तित प्रत्येक फ्रेम आकार बदलने के लिए अपने Graphics2D कोड का उपयोग करने (यदि आप एक जोड़ने की आवश्यकता होगी है एलेक्स की छविफ्रेम कक्षा में सेट इमेज विधि), फिर सरणी को एक gif में बदलने के लिए इलियट के कोड का उपयोग करें!

public static void main(String[] args) 
{ 
    try { 
    File imageFile = new File("InputFile"); 
    FileInputStream fiStream = new FileInputStream(imageFile); 

    ImageFrame[] frames = readGif(fiStream); 
    for(int i = 0; i < frames.length; i++){ 
     //code to resize the image 
     BufferedImage image = ImageUtilities.resizeImage(frames[ i ].getImage(), newWidth, newHeight); 
     frames[ i ].setImage(image); 
    } 

    ImageOutputStream output = 
     new FileImageOutputStream(new File("OutputFile")); 

    GifSequenceWriter writer = 
     new GifSequenceWriter(output, frames[0].getImage().getType(), frames[0].getDelay(), true); 

    writer.writeToSequence(frames[0].getImage()); 
    for (int i = 1; i < frames.length; i++) { 
     BufferedImage nextImage = frames[i].getImage(); 
     writer.writeToSequence(nextImage); 
    } 

    writer.close(); 
    output.close(); 
    } 
    catch (FileNotFoundException e) { 
    System.out.println("File not found"); 
    } 
    catch (IOException e) { 
    System.out.println("IO Exception"); 
    } 
} 

इस कोड है, तथापि, फ्रेम के बीच समय elapsing के विभिन्न राशि के साथ gif छवियों के लिए खाते में नहीं है: यहाँ की तरह मेरा क्या दिखता है।

+1

बहुत बढ़िया था, इतना धन्यवाद। पूरी तरह से हल किया गया है और मैं gifs का आकार बदल सकते हैं और अब एनीमेशन रख सकते हैं। केवल ध्यान दें कि आपको फ्रेम [0] .getDelay() 10 से गुणा करना चाहिए क्योंकि GIFSequenceWriter के अंदर यह 10 (मिलीसेकंड से समायोजित करने के लिए) द्वारा विभाजित होता है – Erich

+0

यह अच्छी तरह से काम करता है लेकिन आकार 1 एमबी और 222 फ्रेम के gif के लिए लगभग 200 एमबी लेता है। स्मृति उपयोग को कम करने के लिए कोई कारण है ?? – Vipul

1

तो मुझे पता है कि यह पुराना है लेकिन मुझे एक समाधान मिला, मैं जावा 8 का उपयोग कर रहा हूं यह सुनिश्चित नहीं है कि यह अन्य संस्करणों के साथ काम करेगा या नहीं।

ImageIcon image = ? (whatever/wherever your gif is) 
    int width = 100; 
    int height = 100; 
    image.setImage(image.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT)); 

आप यहाँ SCALE_SMOOTH और SCALE_AREA_AVREAGING मेरे लिए काम नहीं किया के अलावा सूचीबद्ध करने के लिए SCALE_DEFAULT बदल सकते हैं, तो उसे खाली https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html

+0

यह वह तरीका है जिसका मैं उपयोग करता हूं। SCALE_SMOOTH और SCALE_AREA_AVERAGING कवर के तहत एक ही एल्गोरिदम हैं, और मैं पुष्टि कर सकता हूं कि अगर मैं इसे एनिमेटेड जीआईएफ खिलाता हूं तो मुझे एक खाली छवि आउटपुट मिलता है। उस मामले में SCALE_DEFAULT से सर्वोत्तम परिणाम। अन्य छवियों के लिए, SCALE_SMOOTH कुछ हद तक अच्छे परिणाम उत्पन्न करता है। – JakeRobb