[英]Rotate BufferedImage with transparent background
我有一個透明背景的圖像。 我想將此圖像旋轉到特定角度,並保持生成的圖像的透明背景。 為此,我使用以下方法:
public static BufferedImage rotateImage(BufferedImage image, double angle, Color backgroundColor) {
System.out.println(image.getType());
double theta = Math.toRadians(angle);
double sin = Math.abs(Math.sin(theta));
double cos = Math.abs(Math.cos(theta));
int w = image.getWidth();
int h = image.getHeight();
int newW = (int) Math.floor(w * cos + h * sin);
int newH = (int) Math.floor(h * cos + w * sin);
BufferedImage tmp = new BufferedImage(newW, newH, image.getType());
Graphics2D g2d = tmp.createGraphics();
if (backgroundColor != null) {
g2d.setColor(backgroundColor);
g2d.fillRect(0, 0, newW, newH);
}
g2d.fillRect(0, 0, newW, newH);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.translate((newW - w) / 2, (newH - h) / 2);
g2d.rotate(theta, w / 2, h / 2);
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return tmp;
}
我用background = null調用它:
BufferedImage image = ImageIO.read(file);
rotateImage(image, 4, null);
ImageIO.write(bi, "PNG", new File("image.png"));
但是生成的image.png的背景是白色。 我在做錯什么以及如何正確保持image.png的透明背景?
我對Graphics.drawImage()
的行為有些疑惑。 也許其他人可以對此發表評論。
但是, Graphics2D.drawRenderedImage()
可以處理。 它需要一個AffineTransform
來控制旋轉。 下面的示例很好地工作。 您可能對最終圖像尺寸和旋轉圖像的位置有其他要求。
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
public class ImageRotation {
public static void main(String[] args) {
ImageRotation rotation = new ImageRotation();
rotation.rotate("input.png", 45, "output.png");
}
public void rotate(String inputImageFilename, double angle, String outputImageFilename) {
try {
BufferedImage inputImage = ImageIO.read(new File(inputImageFilename));
BufferedImage outputImage = rotateImage(inputImage, angle);
ImageIO.write(outputImage, "PNG", new File(outputImageFilename));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private BufferedImage rotateImage(BufferedImage sourceImage, double angle) {
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
BufferedImage destImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = destImage.createGraphics();
AffineTransform transform = new AffineTransform();
transform.rotate(angle / 180 * Math.PI, width / 2 , height / 2);
g2d.drawRenderedImage(sourceImage, transform);
g2d.dispose();
return destImage;
}
}
更新資料
盡管以上代碼適用於大多數PNG,但不適用於蝶形動物正在使用的圖像 。 我分析了圖像:
據我所知這是完全合法的。 但是,ImageIO沒有實現此組合。 如果圖像沒有調色板,則它只會忽略tRNS塊,因此會忽略透明度信息。 這很可能是一個錯誤。
現在,您基本上有兩個選擇:
有效的PNG文件的輸入和輸出
輸入圖片:
輸出圖像:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.