最近開發當中,通過JAVA對圖片進行了很多的操作,之前很少接觸這方面的知識,特此記錄下來
讀取圖片
//讀取圖片 通過JAVA自帶的ImageIO裏面的read方法
BufferedImage bufImage = ImageIO.read(File input);
BufferedImage bufImage = ImageIO.read(URL input);
BufferedImage bufImage = ImageIO.read(InputStream input);
BufferedImage bufImage = ImageIO.read(ImageInputStream input)
保存圖片
/**
* image:RenderedImage 接口的實現類, BufferedImage 實現了 RenderedImage 接口
* formatName: 保存的圖片格式的名稱
* output: 結果輸出位置
*/
ImageIO.write(RenderedImage image, String formatName, File output);
ImageIO.write(RenderedImage image, String formatName, OutputStream output);
繪製圖片
/**
* 創建一個指定寬高的圖片內存對象
* width : 寬度
* height : 高度
* imageType : 圖片類型 參數爲BufferedImage 自身定義的常量
* TYPE_3BYTE_BGR :代表8位RGB分量圖像
TYPE_INT_ARGB :代表8位RGBA顏色組件包裝成整數像素的圖像
......
*/
BufferedImage image = new BufferedImage(width, height, imageType);
//獲取圖片的畫布
Graphics2D graphics = image.createGraphics();
//然後使用 Graphics 類在圖片上繪製線段、矩形、圖片、文本,設置背景顏色等等操作
// 設置畫布顏色
void setColor(Color c)
// 設置字體顏色
void setFont(Font font)
// 設置線的寬度
setStroke(Stroke s)
// 設置背景顏色
void setBackground(Color c)
// 擦除某一區域(擦除後顯示背景色)
void clearRect(int x, int y, int width, int height)
// 回收 Graphics 釋放資源 操作完畢後一定要釋放資源
void dispose()
// 繪製一條線段(如果兩點爲同一點,則繪製點)
void drawLine(int x1, int y1, int x2, int y2)
// 繪製一個矩形(空心)
void drawRect(int x, int y, int width, int height)
// 繪製一個橢圓(空心)
void drawOval(int x, int y, int width, int height)
// 繪製一個圓弧(弧線)
void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
// 繪製一張圖片 ImageObserver:接收有關 Image 信息通知的異步更新接口,沒用到直接傳空
boolean drawImage(Image image, int x, int y, ImageObserver observer)
// 繪製一段文本
void drawString(String str, int x, int y)
...........................
縮放圖片
/**
*@param width: 縮放後的寬度
*@param height: 縮放後的高度
*@param hints: 圖像重採樣算法的類型
*
* hints 參數取值爲以下之一(Image 類中的常量):
* SCALE_AREA_AVERAGING: 使用 Area Averaging 圖像縮放算法;
* SCALE_DEFAULT: 使用默認的圖像縮放算法;
* SCALE_SMOOTH: 選擇圖像平滑度比縮放速度具有更高優先級的圖像縮放算法。
* ......
*/
Image getScaledInstance(int width, int height, int hints);
縮放的使用實例代碼:
/**
* JAVA 圖像等比縮放
* @param srcImageFile 縮放的圖片
* @param destImageFile 縮放後的圖片
* @param scale 縮放比例
* @return
*/
public static boolean scale(File srcImageFile, File destImageFile,float scale){
try {
//使用ImageIO的read方法讀取圖片
BufferedImage read = ImageIO.read(srcImageFile);
//獲取縮放後的寬高
int width = (int) (read.getWidth()*scale);
int height = (int) (read.getHeight()*scale);
//調用縮放方法獲取縮放後的圖片
Image img = read.getScaledInstance(width , height, Image.SCALE_DEFAULT);
//創建一個新的緩存圖片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//獲取畫筆
Graphics2D graphics = image.createGraphics();
//將Image對象畫在畫布上,最後一個參數,ImageObserver:接收有關 Image 信息通知的異步更新接口,沒用到直接傳空
graphics.drawImage(img, 0, 0,null);
//一定要釋放資源
graphics.dispose();
//獲取到文件的後綴名
String fileName = srcImageFile.getName();
String formatName = fileName.substring(fileName.lastIndexOf(".") + 1);
//使用ImageIO的write方法進行輸出
ImageIO.write(image,formatName,destImageFile);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
裁剪圖片
/**
*
* @param x 裁剪時x的座標(左上角)
* @param y 裁剪時y的座標(左上角)
* @param width 裁剪後的圖片寬度
* @param height 裁剪後的圖片高度
*
* 裁剪後返回的是一個新的圖片緩存對象
*/
BufferedImage getSubimage(int x,int y, int width ,int height )
裁剪圖片實例代碼:
/**
* JAVA裁剪圖片
* @param srcImageFile 需要裁剪的圖片
* @param x 裁剪時x的座標(左上角)
* @param y 裁剪時y的座標(左上角)
* @param width 裁剪後的圖片寬度
* @param height 裁剪後的圖片高度
* @param destImageFile 裁剪後的圖片
* @return
*/
public static boolean cut(File srcImageFile, int x,int y,int width,int height,File destImageFile){
try {
//使用ImageIO的read方法讀取圖片
BufferedImage read = ImageIO.read(srcImageFile);
//調用裁剪方法
BufferedImage image = read.getSubimage(x, y, width, height);
//獲取到文件的後綴名
String fileName = srcImageFile.getName();
String formatName = fileName.substring(fileName.lastIndexOf(".") + 1);
//使用ImageIO的write方法進行輸出
ImageIO.write(image,formatName,destImageFile);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
添加水印
水印的添加主要是通過下面的方法進行的添加。
// 繪製一張圖片 ImageObserver:接收有關 Image 信息通知的異步更新接口,沒用到直接傳空
boolean drawImage(Image image, int x, int y, ImageObserver observer)
//設置水印透明度
void setComposite(Composite comp)
// 繪製一段文本
void drawString(String str, int x, int y)
文本水印
/**
* JAVA添加文字水印
* @param srcImageFile 目標圖片
* @param destImageFile 結果圖片
* @param text 文字內容
* @param x 水印x座標
* @param y 水印y座標
* @return
*/
public static boolean watermarkText(File srcImageFile, File destImageFile, String text,int x,int y) {
try {
//使用ImageIO的read方法讀取圖片
BufferedImage read = ImageIO.read(srcImageFile);
Graphics2D graphics = read.createGraphics();
// 設置“抗鋸齒”的屬性
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 設置字體類型和大小
graphics.setFont(new Font("微軟雅黑", Font.PLAIN, 20));
// 設置顏色
graphics.setColor(new Color(255,255,255));
// 添加文字
graphics.drawString(text,x,y);
graphics.dispose();
//獲取到文件的後綴名
String fileName = srcImageFile.getName();
String formatName = fileName.substring(fileName.lastIndexOf(".") + 1);
//使用ImageIO的write方法進行輸出
ImageIO.write(read,formatName,destImageFile);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
圖片水印
/**
* JAVA添加文字水印
* @param srcImageFile 目標圖片
* @param destImageFile 結果圖片
* @param waterImage 水印圖片
* @param x 水印x座標
* @param y 水印y座標
* @return
*/
public static boolean watermarkImage(File srcImageFile,File destImageFile, File waterImage,int x,int y) {
try {
//使用ImageIO的read方法讀取圖片
BufferedImage read = ImageIO.read(srcImageFile);
BufferedImage image = ImageIO.read(waterImage);
//獲取畫布
Graphics2D graphics = read.createGraphics();
//設置透明度爲0.5
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,0.5f));
//添加水印
graphics.drawImage(image,x,y,null);
//關閉透明度
//graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
graphics.dispose();
//獲取到文件的後綴名
String fileName = srcImageFile.getName();
String formatName = fileName.substring(fileName.lastIndexOf(".") + 1);
//使用ImageIO的write方法進行輸出
ImageIO.write(read,formatName,destImageFile);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
如何擦除水印?
第一種方法 :
// 擦除某一區域(擦除後顯示背景色)
void clearRect(int x, int y, int width, int height)
第二種方法:色素替代法
找到水印的顏色編碼,然後用背景色顏色編碼替代。
代碼實現:略 (這種清除水印的需求還是交給PS這種專業軟件去做吧)
貝塞爾曲線
通常繪製線段直接使用一下的方法就可以了drawLine方法就可以了。但是在實現曲線的時候就很難看,所以需要用到貝塞爾曲線。
可以通過Path類來實現貝塞爾曲線的效果
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
// 設置“抗鋸齒”的屬性
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//獲取路徑操作
Path2D path = new GeneralPath();
//通過移動到指定的浮點精度指定的指定的座標,向路徑添加一個點。
path.moveTo(192, 18);
//添加一個彎曲段,由兩個新定義的點,通過繪製一條二次曲線相交的當前座標和指定的座標 (x2,y2)的路徑,使用指定的點 (x1,y1)作爲二次參考
path.quadTo(120, 12, 253, 67);
graphics.draw(path);
graphics.dispose();
總結
JAVA操作圖片的話算是一個非常冷門的功能了,最多就是圖片的縮放,裁剪,水印這三種情況。如果需要進行一些額外的操作的話,就非常需要認真的查閱下JDK的API,並且JAVA操作圖片調試起來也非常的不方便。總的來說就是複雜的圖片操作需求還是交給更專業的軟件(PS)來進行操作吧!!!
JDK1.8在線API