2012-10-14 77 views
6

Tôi có Hình ảnh có kích thước nói 800x800 có kích thước 170 kb. Tôi muốn thay đổi kích thước hình ảnh này để nói 600x600. Sau khi thay đổi kích thước, tôi muốn giảm kích thước hình ảnh. Tôi có thể làm cái này như thế nào?Thay đổi kích thước hình ảnh trong Java để giảm kích thước hình ảnh

+0

Bạn có thể xem http://stackoverflow.com/questions/11959758/java-maintaining-aspect-ratio-of-jpanel-background-image/11959928#11959928 – MadProgrammer

+0

1) * "Sau khi thay đổi kích thước tôi muốn kích thước hình ảnh sẽ bị giảm. "* Khi được giữ trong bộ nhớ, hoặc được tuần tự hóa thành PNG, JPG hoặc GIF? Việc đầu tiên sẽ dẫn đến giảm byte, thứ 2 thường không. 2) Định dạng hình ảnh là gì? (PNG, GIF, JPEG ..) –

+0

Nếu định dạng là JPEG, rất có thể sẽ hiệu quả hơn để giảm kích thước byte hình ảnh trên đĩa bằng cách tăng tỷ lệ nén. Xem ['ImageCompressionDemo'] (http://stackoverflow.com/a/5998015/418556) cho ví dụ nguồn. –

Trả lời

13

Bạn không cần thư viện xử lý hình ảnh đầy đủ để chỉ cần thay đổi kích thước hình ảnh.

Phương pháp khuyến cáo là sử dụng Bilinear tiến rộng, như vậy (bạn có thể sử dụng phương pháp này như là trong mã của bạn):

public BufferedImage scale(BufferedImage img, int targetWidth, int targetHeight) { 

    int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; 
    BufferedImage ret = img; 
    BufferedImage scratchImage = null; 
    Graphics2D g2 = null; 

    int w = img.getWidth(); 
    int h = img.getHeight(); 

    int prevW = w; 
    int prevH = h; 

    do { 
     if (w > targetWidth) { 
      w /= 2; 
      w = (w < targetWidth) ? targetWidth : w; 
     } 

     if (h > targetHeight) { 
      h /= 2; 
      h = (h < targetHeight) ? targetHeight : h; 
     } 

     if (scratchImage == null) { 
      scratchImage = new BufferedImage(w, h, type); 
      g2 = scratchImage.createGraphics(); 
     } 

     g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
       RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
     g2.drawImage(ret, 0, 0, w, h, 0, 0, prevW, prevH, null); 

     prevW = w; 
     prevH = h; 
     ret = scratchImage; 
    } while (w != targetWidth || h != targetHeight); 

    if (g2 != null) { 
     g2.dispose(); 
    } 

    if (targetWidth != ret.getWidth() || targetHeight != ret.getHeight()) { 
     scratchImage = new BufferedImage(targetWidth, targetHeight, type); 
     g2 = scratchImage.createGraphics(); 
     g2.drawImage(ret, 0, 0, null); 
     g2.dispose(); 
     ret = scratchImage; 
    } 

    return ret; 

} 

Mã sửa đổi và làm sạch từ bản gốc tại Filthy Rich Clients.


Dựa trên nhận xét của bạn, bạn có thể làm giảm chất lượng và mã hóa JPEG byte như vậy:

image là BufferedImage.

ByteArrayOutputStream os = new ByteArrayOutputStream(); 
ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next(); 

ImageWriteParam param = writer.getDefaultWriteParam(); 
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
param.setCompressionQuality(0.2f); // Change this, float between 0.0 and 1.0 

writer.setOutput(ImageIO.createImageOutputStream(os)); 
writer.write(null, new IIOImage(image, null, null), param); 
writer.dispose(); 

Bây giờ, kể từ khi os là một ByteArrayOutputStream, bạn có thể Base64 mã hóa nó.

String base64 = Base64.encode(os.toByteArray()); 
+0

Tôi muốn giảm kích thước hình ảnh (tính theo byte) sau khi thay đổi kích cỡ để tôi có thể gửi nó qua ổ cắm. Dataoutputstream nói rằng chuỗi được mã hóa (Base64) quá lớn. – Madeyedexter

+0

Thay vào đó, Base64 mã hóa các byte JPEG. Bạn có thể sử dụng 'ImageIO' cho việc này. – LanguagesNamedAfterCofee

+0

@Danish Xem chỉnh sửa của tôi – LanguagesNamedAfterCofee

3

Sử dụng một số khung làm việc tốt hỗ trợ Xử lý hình ảnh qua Java, ví dụ: IamageJ

Ngoài ra còn có một số hỗ trợ cơ bản có sẵn trong Java thông qua một số lớp như MemoryImageSourcePixelGrabber.

+0

Tôi đã kiểm tra. Tôi muốn làm điều này trong chương trình Java của tôi! – Madeyedexter

+0

Tôi đã cập nhật câu trả lời với thông tin Hỗ trợ cơ bản trong Core Java. Hy vọng rằng sẽ giúp. –

5

Bạn có thể sử dụng Java, Apache2 mã nguồn mở 100% imgscalr library (một lớp tĩnh duy nhất) và làm một cái gì đó như thế này:

import org.imgscalr.Scalr.*; // static imports are awesome with the lib 

... some class code ... 

// This is a super-contrived method name, I just wanted to incorporate 
// the details from your question accurately. 
public static void resizeImageTo600x600(BufferedImage image) { 
    ImageIO.write(resize(image, 600), "JPG", new File("/path/to/file.jpg")); 
} 

LƯU Ý: Nếu trông lẻ, các tĩnh trên nhập khẩu cho phép tôi sử dụng cuộc gọi thay đổi kích thước trực tiếp mà không chỉ định Scalr.resize (...)

Ngoài ra, nếu chất lượng của hình ảnh thu nhỏ được viết ra không giống đủ tốt (nó sẽ được viết ra một cách nhanh chóng mặc dù), bạn có thể sử dụng nhiều lập luận cho thay đổi kích thước phương pháp như vậy:

public static void resizeImageTo600x600(BufferedImage image) { 
    ImageIO.write(resize(image, Method.ULTRA_QUALITY, 600), "JPG", new File("/path/to/file.jpg")); 
} 

.. và bạn thậm chí có thể áp dụng một BufferedImageOp đến kết quả để làm mềm nó trong trường hợp thu hẹp làm cho giao diện hình ảnh để jaggy:

public static void resizeImageTo600x600(BufferedImage image) { 
    ImageIO.write(resize(image, Method.ULTRA_QUALITY, 600, Scalr.OP_ANTIALIAS), "JPG", new File("/path/to/file.jpg")); 
} 

bạn có thể bắt đầu chơi xung quanh với thư viện bởi chỉ cần thêm các entry dep sau trong Maven POM (imgscalr của bạn là ở Mã trung gian của Maven):

<dependency> 
    <groupId>org.imgscalr</groupId> 
    <artifactId>imgscalr-lib</artifactId> 
    <version>4.2</version> 
    <type>jar</type> 
    <scope>compile</scope> 
</dependency> 
+0

Tôi không hiểu giấy phép. Tôi có thể sử dụng điều này trong một trang web cá nhân không? – Ced

+0

Ngoài ra nếu hình ảnh nhỏ hơn, nó sẽ mở rộng? – Ced

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