最近工作上用到圖檔旋轉,是以來偏圖檔旋轉的文章。其中碰到不少坑。
以下實作了旋轉90度的倍數。友善我們了解旋轉是怎麼做的 ,如果要旋轉任意角度,可以用Java自帶的thumbnails(文章後面介紹)
import org.springframework.util.Base64Utils;
import net.coobird.thumbnailator.Thumbnails;
/**
* 旋轉圖檔
* @param old_img
* @param degess 旋轉度數 負數為逆時針 //如果寬高比大于1 不旋轉
* @return
* @throws IOException
*/
public static BufferedImage rotateImage(BufferedImage bi, String times ) {
int width = bi.getWidth();
int height = bi.getHeight();
BufferedImage biFlip = null;
try {
int count = Integer.valueOf(times);
if(count>=){
count = count % ;
}
if(count==) return bi;
if(count==){
biFlip = new BufferedImage(height,width, bi.getType());
for(int i=; i<width; i++){
for(int j=; j<height; j++){
biFlip.setRGB(height--j, i, bi.getRGB(i, j));//順時針旋轉
//旋轉公式 R*(x,y) = (-y,x)
}
}
}else if(count==){
//旋轉180度
biFlip = new BufferedImage(width,height, bi.getType());
for(int i=; i<width; i++){
for(int j=; j<height; j++){
biFlip.setRGB(width--i, height--j, bi.getRGB(i, j));//順時針旋轉180
}
}
}else {
//逆時針旋轉90 == 旋轉270度
biFlip = new BufferedImage(height,width, bi.getType());
for(int i=; i<width; i++){
for(int j=; j<height; j++){
biFlip.setRGB(j, width--i, bi.getRGB(i, j));
}
}
}
} catch(Exception e){
e.printStackTrace();
return bi;
}finally {
}
return biFlip;
}
圖檔轉base64
public static String encodeToString(BufferedImage image) {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, "jpg", bos);
byte[] imageBytes = bos.toByteArray();
imageString = Base64Utils.encodeToString(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
base64轉圖檔
public static BufferedImage baseToBufferedImage(String base64Sign){
ByteArrayOutputStream os = new ByteArrayOutputStream();
BufferedImage img = null;
byte[] buffer=null;
BufferedImage bufferImg =null ;
try {
buffer = Base64Utils.decodeFromString(base64Sign);
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
bufferImg = ImageIO.read(input);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bufferImg;
}
**
**
下面介紹Thumbnails
1 Thumbnails.of(images)
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
操作圖檔的來源
可以是BufferedImage File InputStream URL 等途徑
**
2 具體操作
**
a 壓縮圖檔(拉伸圖檔)
壓縮圖檔(選擇操作的大小) size()是按照原圖一width為準等比例壓縮。forceSize()是強制壓縮,可能導緻圖檔變形。
也可以用scale指定比例,第二個方法可以指定長款分别壓縮多少倍,等于圖檔拉伸操作。
b 旋轉圖檔
Thumbnails.of(“”).scale(1).rotate(10);
旋轉度數按順時針旋轉,如果要逆時針,可以傳入負數。必須先指定大小既scale或用size指定。
3**
輸出操作後的圖檔
**
可以作為輸出的方式也挺多的 。
總結 :
不管哪種方式實作,還是要注意幾個問題
1 是圖檔旋轉後編碼的時候用BASE64Decoder編碼解碼,而BASE64Decoder編碼時預設每隔76個字元加一個換行,導緻旋轉後編碼變的很大,并且有換行的編碼在轉圖檔的時候就有問題,用spring自帶的工具org.springframework.util.Base64Utils編解碼;。
2是對于空白圖檔,在轉成BufferedImage時Java把透明背景設定成了黑色背景,可以在操作之前把圖檔設定成白色背景。
Thumbnails其他操作
圖檔剪裁
/**
* 圖檔中心400*400的區域
*/
Thumbnails.of("images/test.jpg").sourceRegion(Positions.CENTER, , ).size(, ).keepAspectRatio(false)
.toFile("C:/image_region_center.jpg");
/**
* 圖檔右下400*400的區域
*/
Thumbnails.of("images/test.jpg").sourceRegion(Positions.BOTTOM_RIGHT, , ).size(, ).keepAspectRatio(false)
.toFile("C:/image_region_bootom_right.jpg");
/**
* 指定坐标
*/
Thumbnails.of("images/test.jpg").sourceRegion(, , , ).size(, ).keepAspectRatio(false).toFile("C:/image_region_coord.jpg");
/**
* watermark(位置,水印圖,透明度)
*/
Thumbnails.of("images/test.jpg").size(, ).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("images/watermark.png")), f)
.outputQuality(f).toFile("C:/image_watermark_bottom_right.jpg");
Thumbnails.of("images/test.jpg").size(, ).watermark(Positions.CENTER, ImageIO.read(new File("images/watermark.png")), f)
.outputQuality(f).toFile("C:/image_watermark_center.jpg");