2012-02-22 19 views
5

sto utilizzando Graphics2D in java per ridimensionare le immagini, funziona perfettamente con jpg, png e altri formati. il mio problema sono le immagini GIF animate, dopo il ridimensionamento l'animazione è sparita!ridimensionamento delle GIF animate mantenendo l'animazione utilizzando java

Ecco il metodo sto usando:

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

così, qualche indizio Come posso mantenere sul gif animate dopo ridimensionamento? Grazie.

risposta

4

Ho trovato due fonti che, se combinate, possono essere utilizzate per ridimensionare l'immagine mantenendo l'animazione.

Su questa domanda ( Convert each animated GIF frame to a separate BufferedImage) cercare la risposta di Alex Orzechowski. Il suo codice prende un file gif e lo converte in una matrice di ImageFrame (che è una classe che ha creato che racchiude una BufferedImage). Quindi guarda questo codice che converte una sequenza di BufferedImages in un file gif (http://elliot.kroo.net/software/java/GifSequenceWriter/).

Come probabilmente si può intuire, tutto ciò che occorre fare è caricare la gif, utilizzare il codice di Alex per convertirlo in una serie di ImageFiles/BufferedImages, utilizzare il codice Graphics2D per ridimensionare ogni fotogramma (è necessario aggiungere un imposta il metodoImage alla classe ImageFrame di Alex), quindi usa il codice di Elliot per convertire l'array in una gif! Ecco cosa miniera assomiglia:

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

Questo codice, tuttavia, non rappresentano immagini GIF con diverse quantità di tempo che intercorre tra i fotogrammi.

+1

impressionante, grazie mille. Completamente risolto e posso ridimensionare le gif e mantenere l'animazione ora. Solo nota è necessario moltiplicare i fotogrammi [0] .getDelay() per 10 perché all'interno di GifSequenceWriter divide per 10 (per regolare da millisecondi) – Erich

+0

Funziona bene ma richiede circa 200 MB per gif di dimensioni 1 MB e 222 fotogrammi. c'è qualche motivo per ridurre l'utilizzo della memoria ?? – Vipul

1

Quindi so che questo è vecchio ma ho trovato una soluzione, sto usando Java 8 non so se funzionerà con altre versioni.

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

è possibile modificare SCALE_DEFAULT a quelle elencate qui tranne che per SCALE_SMOOTH e SCALE_AREA_AVREAGING non ha funzionato per me, era vuoto https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html

+0

Questo è il metodo che uso. SCALE_SMOOTH e SCALE_AREA_AVERAGING sono lo stesso algoritmo sotto le copertine e posso confermare che ottengo un'immagine vuota se la nutro con una GIF animata. I migliori risultati da SCALE_DEFAULT in questo caso. Per altre immagini, SCALE_SMOOTH produce risultati leggermente migliori. – JakeRobb

Problemi correlati