2012-02-22 23 views
5

tôi đang sử dụng Graphics2D trong java để thay đổi kích thước hình ảnh, nó hoạt động hoàn hảo với jpg, png và các định dạng khác. vấn đề của tôi là hình ảnh GIF động, sau khi định lại kích thước hoạt ảnh đã biến mất!thay đổi kích thước GIF động trong khi vẫn giữ hoạt ảnh bằng cách sử dụng java

ở đây là phương pháp đang sử dụng:

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

như vậy, bất kỳ manh mối như thế nào tôi có thể giữ trên gif động sau khi tái định cỡ? Cảm ơn.

Trả lời

4

Tôi đã tìm thấy hai nguồn khi kết hợp có thể được sử dụng để thay đổi kích thước hình ảnh trong khi vẫn giữ hoạt ảnh.

Về câu hỏi này ( Convert each animated GIF frame to a separate BufferedImage) tìm câu trả lời của Alex Orzechowski. Mã của anh ta lấy một tệp gif và chuyển đổi nó thành một mảng của ImageFrames (đó là một lớp mà anh ta tạo ra để kết thúc một BufferedImage). Sau đó, xem mã này chuyển đổi một chuỗi các BufferedImages thành một tệp gif (http://elliot.kroo.net/software/java/GifSequenceWriter/). Như bạn có thể đoán, tất cả những gì bạn cần làm là tải lên gif, sử dụng mã của Alex để chuyển đổi nó thành một mảng ImageFiles/BufferedImages, sử dụng mã Graphics2D của bạn để thay đổi kích thước mỗi khung hình (bạn sẽ cần thêm phương thức setImage cho lớp ImageFrame của Alex), sau đó sử dụng mã của Elliot để chuyển đổi mảng thành gif! Dưới đây là những gì tôi trông giống như:

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

Mã này không tính đến hình ảnh gif với khoảng thời gian khác nhau giữa các khung hình.

+1

Awesome, cảm ơn rất nhiều. Hoàn toàn giải quyết nó và tôi có thể thay đổi kích cỡ gifs và giữ cho hình ảnh động ngay bây giờ. Chỉ cần lưu ý là bạn nên nhân khung [0] .getDelay() bởi 10 vì bên trong GifSequenceWriter nó chia cho 10 (để điều chỉnh từ mili giây) – Erich

+0

Nó hoạt động tốt nhưng mất khoảng 200MB cho gif kích thước 1MB và 222 khung. có bất kỳ lý do gì để giảm mức sử dụng bộ nhớ không ?? – Vipul

1

Vì vậy, tôi biết điều này là cũ nhưng tôi tìm thấy một giải pháp, tôi đang sử dụng Java 8 không chắc chắn nếu nó sẽ làm việc với các phiên bản khác.

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

bạn có thể thay đổi SCALE_DEFAULT để những người được liệt kê ở đây trừ SCALE_SMOOTH và SCALE_AREA_AVREAGING không làm việc cho tôi, đó là trống https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html

+0

Đây là phương pháp tôi sử dụng. SCALE_SMOOTH và SCALE_AREA_AVERAGING là cùng một thuật toán trong phần trình bày và tôi có thể xác nhận rằng tôi nhận được một đầu ra hình ảnh trống nếu tôi cho nó một GIF động. Kết quả tốt nhất từ ​​SCALE_DEFAULT trong trường hợp đó. Đối với các hình ảnh khác, SCALE_SMOOTH tạo ra kết quả tốt hơn một chút. – JakeRobb

Các vấn đề liên quan