2012-03-17 36 views
5

Tôi chỉ đang cố xoay một tệp JPG bằng 90 độ. Tuy nhiên hình ảnh đầu ra mã của tôi (BufferedImage) hoàn toàn màu đen.Xoay hình ảnh Java với AffineTransform xuất ra hình ảnh đen, nhưng hoạt động tốt khi thay đổi kích thước

Đây là cách để tái tạo: (Tải 3.jpg here)

private static BufferedImage transform(BufferedImage originalImage) { 
    BufferedImage newImage = null; 
    AffineTransform tx = new AffineTransform(); 
    tx.rotate(Math.PI/2, originalImage.getWidth()/2, originalImage.getHeight()/2); 

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC); 
    newImage = op.filter(originalImage, newImage); 

    return newImage; 
} 

public static void main(String[] args) throws Exception { 
    BufferedImage bi = transform(ImageIO.read(new File(
      "3.jpg"))); 
    ImageIO.write(bi, "jpg", new File("out.jpg")); 

} 

Có gì sai ở đây?

(nếu tôi cung cấp cho sản lượng đen này BufferedImage thư viện hình ảnh resizer, nó được thay đổi kích cỡ tốt, hình ảnh ban đầu vẫn còn đó.)

Trả lời

13

Đi qua một BufferedImage mới vào bộ lọc() phương pháp chứ không phải là để cho nó tạo ra nó công trình riêng (không hoàn toàn đen).

Ngoài ra, biến đổi không hoạt động chính xác, hình ảnh đã được bù đắp ở đích. Tôi đã có thể sửa chữa nó bằng cách áp dụng thủ công các bản dịch cần thiết, lưu ý những công việc này theo thứ tự ngược lại, và trong ảnh đích chiều rộng = chiều cao cũ và chiều cao = chiều rộng cũ.

AffineTransform tx = new AffineTransform(); 

// last, width = height and height = width :) 
tx.translate(originalImage.getHeight()/2,originalImage.getWidth()/2); 
tx.rotate(Math.PI/2); 
// first - center image at the origin so rotate works OK 
tx.translate(-originalImage.getWidth()/2,-originalImage.getHeight()/2); 

AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); 

// new destination image where height = width and width = height. 
BufferedImage newImage =new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), originalImage.getType()); 
op.filter(originalImage, newImage); 

javadoc cho bộ lọc() tuyên bố rằng nó sẽ tạo BufferedImage cho bạn, tôi vẫn không chắc tại sao điều này không hiệu quả, phải có sự cố ở đây.

If the destination image is null, a BufferedImage is created with the source ColorModel. 
5

Nếu bạn đã mở cửa cho các ý tưởng của việc sử dụng một lib bên thứ 3 (rất nhỏ, chỉ cần 2 lớp) imgscalr thể làm điều này cho bạn trong một dòng duy nhất trong khi làm việc xung quanh tất cả các gotchas lọc rằng các loại hình ảnh khác nhau có thể nguyên nhân.

Sử dụng Scalr.rotate(...) sẽ giống như thế này:

BufferedImage newImage = Scalr.rotate(originalImage, Rotation.CW_90); 

Nếu xoay này là một phần của một ứng dụng lớn hơn mà xử lý hình ảnh, thậm chí bạn có thể làm điều này không đồng bộ nếu bạn cần đó (AsyncScalr class).

imgscalr là theo giấy phép Apache 2 và tất cả các nguồn đều có sẵn; nếu bạn muốn tự làm điều này bằng tay, hãy đọc qua số code for the rotate() method, tôi đã ghi lại tất cả các dấu hiệu có thể nảy sinh khi làm việc với các bộ lọc trong Java2D.

Hy vọng điều đó sẽ hữu ích!

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