1. 程式人生 > >java對圖片的各種操作(壓縮、加水印(文字或圖片)、旋轉)

java對圖片的各種操作(壓縮、加水印(文字或圖片)、旋轉)


先貼上原始碼,再呼叫測試看效果,整理了3天。如有更好想法或不同見解,歡迎@我([email protected]).
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

/**
 * @author E-mail:
[email protected]
* @version 2015-2-27 下午2:10:52 * * MyImage2 */ public class MyImage2 { private String srcFile; private String destFile; private int width; private int height; private Image img; public String getSrcFile() { return srcFile; } public void setSrcFile(String srcFile) { this.srcFile = srcFile; } public String getDestFile() { return destFile; } public void setDestFile(String destFile) { this.destFile = destFile; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public Image getImg() { return img; } public void setImg(Image img) { this.img = img; } /** * 建構函式 * @param fileName 操作的檔名 * @param newFileName 生成的新檔名 * @throws IOException */ public MyImage2(String fileName,String newFileName) throws IOException { this.srcFile = fileName; this.destFile = newFileName; img = ImageIO.read(new File(fileName)); width = img.getWidth(null);//得到源寬度 height = img.getHeight(null);//得到源高度 } /** * 強制壓縮/放大圖片到固定的大小 * @param newWidth * @param newHeight * @throws IOException */ public void resize(int newWidth,int newHeight) throws IOException{ Image img = Toolkit.getDefaultToolkit().getImage(srcFile); BufferedImage bi_scale = toBufferedImage(img,newWidth,newHeight); //第一種通過檔案流和JPEGImageEncoder近JPEg編碼輸出 FileOutputStream newImageOPS = new FileOutputStream(destFile);//輸出檔案流 /* * JPEGImageEncoder 將影象緩衝資料編碼為 JPEG 資料流。該介面的使用者應在 Raster * 或 BufferedImage 中提供影象資料,在 JPEGEncodeParams 物件中設定必要的引數, * 併成功地開啟 OutputStream(編碼 JPEG 流的目的流)。JPEGImageEncoder 介面可 * 將影象資料編碼為互換的縮略 JPEG 資料流,該資料流將寫入提供給編碼器的 OutputStream 中。 注意:com.sun.image.codec.jpeg 包中的類並不屬於核心 Java API。它們屬於 Sun 釋出的 JDK 和 JRE 產品的組成部分。雖然其它獲得許可方可能選擇釋出這些類,但開發人員不能寄 希望於從非 Sun 實現的軟體中得到它們。我們期望相同的功能最終可以在核心 API 或標準擴 展中得到。 */ com.sun.image.codec.jpeg.JPEGImageEncoder encoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(newImageOPS); encoder.encode(bi_scale);//近JPEG編碼 newImageOPS.close(); //第二種通過圖片流寫入 //ImageIO.write(bi_scale, "JPEG", new File(destFile)); } /** * 生成圖片帶紅的處理方法 * @param image * @param width * @param height * @return */ public static BufferedImage toBufferedImage(Image image,int width,int height) { if (image instanceof BufferedImage) { return (BufferedImage)image; } // This code ensures that all the pixels in the image are loaded image = new ImageIcon(image).getImage(); // Determine if the image has transparent pixels; for this method's // implementation, see e661 Determining If an Image Has Transparent Pixels //boolean hasAlpha = hasAlpha(image); // Create a buffered image with a format that's compatible with the screen BufferedImage bimage = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { // Determine the type of transparency of the new buffered image int transparency = Transparency.OPAQUE; /* if (hasAlpha) { transparency = Transparency.BITMASK; }*/ // Create the buffered image GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); bimage = gc.createCompatibleImage(width, height, transparency); } catch (HeadlessException e) { // The system does not have a screen } if (bimage == null) { // Create a buffered image using the default color model int type = BufferedImage.TYPE_INT_RGB; //int type = BufferedImage.TYPE_3BYTE_BGR;//by wang /*if (hasAlpha) { type = BufferedImage.TYPE_INT_ARGB; }*/ bimage = new BufferedImage(width, height, type); } // Copy image to buffered image Graphics g = bimage.createGraphics(); // Paint the image onto the buffered image g.drawImage(image, 0, 0,width,height, null);////繪製縮小的圖 g.dispose(); return bimage; } /** * 按照固定的比例縮放圖片 * @param t * @throws IOException */ public void resize(double t) throws IOException{ int w = (int)(width*t); int h = (int)(height*t); resize(w,h); } /** * 已寬度為基準,等比例縮放圖片 * @param newWidth * @throws IOException */ public void resizeByWidth(int newWidth) throws IOException{ int h = (int)(height*(new Double(newWidth)/width)); resize(newWidth,h); } /** * 以高度為基準,等比例縮放圖片 * @param newHeight * @throws IOException */ public void resizeByHeight(int newHeight) throws IOException{ int w = (int)(width*(new Double(newHeight)/height)); resize(w,newHeight); } /** * 生成規格 * @throws IOException */ public void resizeFix(int newWidth,int newHeight) throws IOException{ if(width>height || (width/height>newWidth/newHeight)){ resizeByWidth(newWidth); }else{ resizeByHeight(newHeight); } } /** * 新增圖片水印 * @param targetImg 目標圖片路徑,如:C://myPictrue//1.jpg * @param waterImg 水印圖片路徑,如:C://myPictrue//logo.png * @param x 水印圖片距離目標圖片左側的偏移量,如果x<0, 則在正中間 * @param y 水印圖片距離目標圖片上側的偏移量,如果y<0, 則在正中間 * @param alpha 透明度(0.0 -- 1.0, 0.0為完全透明,1.0為完全不透明) * @throws Exception */ public static void pressImage(String targetImg,String waterImg,int x,int y,float alpha) throws Exception{ try { File file = new File(targetImg); Image image = ImageIO.read(file); int width = image.getWidth(null); int height = image.getHeight(null); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, null); Image waterImage = ImageIO.read(new File(waterImg));//水印檔案 int width_wi=waterImage.getWidth(null); int height_wi=waterImage.getHeight(null); if(width<=width_wi || height<=height_wi){ throw new Exception("原圖的寬、高必須大於水印圖的寬、高"); } AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha); int widthDiff = width-width_wi; int heightDiff = height-height_wi; if(x<0){ x = widthDiff/2; }else if(x>widthDiff){ x = widthDiff; } if(y<0){ y = heightDiff/2; }else if(y>heightDiff){ y = heightDiff; } g.drawImage(waterImage, x, y, width_wi,height_wi,null);//水印檔案結束 g.dispose(); ImageIO.write(bufferedImage, "JPEG", file); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 新增文字水印 * @param targetImg 目標圖片路徑,如:C://myPictrue//1.jpg * @param pressText 水印文字, 如:中國證券網 * @param fontName 字型名稱, 如:宋體 * @param fontStyle 字型樣式,如:粗體和斜體(Font.BOLD|Font.ITALIC) * @param fontSize 字型大小,單位為畫素 * @param color 字型顏色 * @param x 水印文字距離目標圖片左側的偏移量,如果x<0, 則在正中間 * @param y 水印文字距離目標圖片上側的偏移量,如果y<0, 則在正中間 * @param alpha 透明度(0.0 -- 1.0, 0.0為完全透明,1.0為完全不透明) */ public static void pressText(String targetImg,String pressText,String fontName,int fontStyle,int fontSize,Color color,int x,int y,float alpha){ try { File file = new File(targetImg); Image image = ImageIO.read(file); int width = image.getWidth(null); int height = image.getHeight(null); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image,0,0, width, height, null); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setColor(color); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); int width_wi = fontSize*getTextLength(pressText); int height_wi = fontSize; int widthDiff = width-width_wi; int heightDiff = height-height_wi; if(x<0){ x = widthDiff/2; }else if(x>widthDiff){ x=widthDiff; } if(y<0){ y = heightDiff/2; }else if(y>heightDiff){ y = heightDiff; } g.drawString(pressText, x, y+height_wi);//水印檔案 g.dispose(); ImageIO.write(bufferedImage, "JPEG", file); } catch (IOException e) { e.printStackTrace(); } } /** * 計算文字畫素長度 * @param text * @return */ private static int getTextLength(String text){ int textLength = text.length(); int length = textLength; for (int i = 0; i < textLength; i++) { int wordLength = String.valueOf(text.charAt(i)).getBytes().length; if(wordLength > 1){ length+=(wordLength-1); } } return length%2==0 ? length/2:length/2+1; } /** * 旋轉任意度數的方法 * @param targetImg * @param degree * @param bgcolor * @throws IOException */ public static void rotateImage(String targetImg, int degree, Color bgcolor) throws IOException { File file = new File(targetImg); BufferedImage sourceImage = ImageIO.read(file); int iw = sourceImage.getWidth();//原始圖象的寬度 int ih = sourceImage.getHeight();//原始圖象的高度 int w = 0; int h = 0; int x = 0; int y = 0; degree = degree % 360; if (degree < 0) degree = 360 + degree;//將角度轉換到0-360度之間 double ang = Math.toRadians(degree);//將角度轉為弧度 /** *確定旋轉後的圖象的高度和寬度 */ if (degree == 180 || degree == 0 || degree == 360) { w = iw; h = ih; } else if (degree == 90 || degree == 270) { w = ih; h = iw; } else { int d = iw + ih; w = (int) (d * Math.abs(Math.cos(ang))); h = (int) (d * Math.abs(Math.sin(ang))); } x = (w / 2) - (iw / 2);//確定原點座標 y = (h / 2) - (ih / 2); BufferedImage rotatedImage = new BufferedImage(w, h, sourceImage.getType()); Graphics2D gs = (Graphics2D)rotatedImage.getGraphics(); if(bgcolor==null){ rotatedImage = gs.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT); }else{ gs.setColor(bgcolor); gs.fillRect(0, 0, w, h);//以給定顏色繪製旋轉後圖片的背景 } //有兩種旋轉使用方式,第一使用AffineTransformOp,第二使用Graphics2D /* * AffineTransform at = new AffineTransform(); at.rotate(ang, w / 2, h / 2);//旋轉圖象 at.translate(x, y); AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC); op.filter(sourceImage, rotatedImage); sourceImage = rotatedImage; ImageIO.write(sourceImage, "PNG", file);//這裡的格式化請使用PNG格式,否則旋轉後會出現紅眼效果 */ BufferedImage bufferedImage = new BufferedImage(w, h, sourceImage.getType()); Graphics2D g = bufferedImage.createGraphics(); if(bgcolor==null){ g.setColor(Color.WHITE); }else{ g.setColor(bgcolor); } g.fillRect(0, 0, w, h);//以給定顏色繪製旋轉後圖片的背景 g.rotate(Math.toRadians(degree), w/2, h/2); g.translate(x, y); g.drawImage(sourceImage, 0, 0, null); g.dispose(); ImageIO.write(bufferedImage, "JPEG", file);//這裡的JPEG也可以是PNG } /** * @param args */ public static void main(String[] args) { /*try { //生成縮圖 MyImage2 image2 = new MyImage2("C:\\Users\\chengjiangbo\\Desktop\\images\\IMG.jpg", "C:\\Users\\chengjiangbo\\Desktop\\images\\IMG_300_100.jpg"); image2.resizeFix(300, 100);//這裡縮圖的比例在方法裡會計算,防止失真。 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ /*try { //加圖片水印 MyImage2.pressImage("C:\\Users\\chengjiangbo\\Desktop\\images\\IMG_300_100.jpg", "C:\\Users\\chengjiangbo\\Desktop\\images\\QRCode.png", 300, 300, 0.5f); } catch (Exception e) { e.printStackTrace(); }*/ //加文字水印 //MyImage2.pressText("C:\\Users\\chengjiangbo\\Desktop\\images\\IMG_300_100.jpg", "江波之印", "宋體", Font.BOLD, 20, Color.WHITE,10, 10, 1f); //旋轉任意度數包括直角(90,180,270,360) try { MyImage2.rotateImage("C:\\Users\\chengjiangbo\\Desktop\\images\\IMG_300_100.jpg", 90,null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }


1、生成縮圖測試:

原圖:


縮圖:


2、加水印測試

加圖片水印:


加文字水印:


3、旋轉任意度數包括直角(90,180,270,360)測試


參考技術連結:

http://hxg1026.iteye.com/blog/667500;

http://blog.csdn.net/mengfei86/article/details/6821553;

http://blog.csdn.net/heliang7/article/details/7309394;

http://www.oschina.net/question/1092_23668;(解決生成的縮圖蒙一層紅的bug);

http://www.cnblogs.com/waya/archive/2008/11/04/1326402.html;

相關推薦

java圖片各種操作(壓縮水印文字圖片旋轉)

先貼上原始碼,再呼叫測試看效果,整理了3天。如有更好想法或不同見解,歡迎@我([email protected]). import java.awt.AlphaComposite; import java.awt.Color; import java.awt.F

藍綠部署金絲雀釋出灰度釋出A/B測試的準確定義

作者: 李佶澳   轉載請保留:原文地址   釋出時間:2018/10/23 14:02:00   說明 藍綠部署 金絲雀釋出 A/B測試 參考 說明

PDF檔案水印怎麼新增文字圖片

如何給PDF檔案新增水印呢?平常處理一些比較重要的檔案來說,這裡就拿製作完之後的PDF檔案來說,為了他人直接挪用自己的編輯成果,大多數人都會給這份PDF檔案新增自己專屬的水印,那大家是否知道PDF新增水印的方法嗎?操作起來其實也比較簡單,下面就跟著小編的方法一起

linux 程序執行緒or子程序資源佔用檢視以及顯示資料的意義

檢視程序: ps -ef | more  (-e:所有程序,-f:全格式) ++++++++++++++++++++++++++++++++++++ + UID :使用者ID                     + + PID :程序ID                

分組對稱金鑰加密演算法——DES3DESDESede TDESAES

一、常用的 "分組對稱金鑰加密演算法" 分為以下3種 (1)DES(Data Encryption Standard,標準加密演算法)   1977年1月,美國政府頒佈:採納IBM公司設計的方案作為非機密資料的正式資料加密標準(DES Data Encryption Sta

Google提供的Thumbnails圖片各種操作(縮放水印翻轉轉換圖片格式)效能比jdk提供的好N倍,壓縮出來的圖片更清晰

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">jar下載:</span><span style="f

Java開源】Thumbnailator輕鬆搞定圖片縮放旋轉水印

概述 Thumbnailator 是一個開源的 Java 專案,它提供了非常簡單的 API 來對圖片進行縮放、旋轉以及加水印的處理。 有多簡單呢?簡單到一行程式碼就可以完成圖片處理。形式如下:Thumbnails.of(new File("path/to/direct

javaDate型別時間的直接操作

方法有很多,這裡是用 Calendar 類 進行時間的操作 是一個抽象類,它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日曆欄位之間的轉換提供了一些方法,併為操作日曆欄位(例如獲得下星期的日期)提供了一些方法。

HTML5 file APIcanvas實現圖片前端JS壓縮並上傳 轉載

www. 手機 回調 pre lan 瀏覽器中 rdp 效果 二進制 一、圖片上傳前端壓縮的現實意義 對於大尺寸圖片的上傳,在前端進行壓縮除了省流量外,最大的意義是極大的提高了用戶體驗。 這種體驗包括兩方面: 由於上傳圖片尺寸比較小,因此上傳速度會比較快,交互會更

java圖片和動圖添水印

port buffere imp 結束 exce cat screen rem *** 這兩天根據需求在做圖片上傳添加水印,實話說重來不知道java還可以這樣操作,既然有個這要求我就去找資料研究了一番,現在把它分享一下,希望能幫到有需要的兄弟。 給普通圖片添加水印和給動圖添

JavaMySQL表操作練習

用navicat新建一個數據庫和表 其中empno為關鍵列 從MySql資料庫中讀表 package sqldemo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Res

java字串相關操作方法

maven: <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.0.0<

java日期相關操作方法

maven: <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.0.0<

JavaList分段操作的方法介紹

有時候,我們需要從一個系統裡匯出資料,並匯入另外一個系統中,而這個資料很大,而資料匯入受到限制,無法實現,這時,我們就需要對資料進行List切分,然後再一個個匯出,最終,實現資料匯入。 對於資料的分段處理,我們可以採用subList方法進行實現,具體用法可參看以下案例: import jav

JAVA資料庫進行操作---弱智的學習記錄

通過java對資料庫進行操作的簡單實現 匯入myql-jdbc的jar包 簡單的程式碼實現 package day10_10; import java.sql.Connection; import java.sql.Driv

java程式碼中操作Redis:單機redis叢集redisspring+redis整合

一、準備 關於redis的一些安裝,可以檢視我的幾篇文章自行安裝:Redis目錄。匯入java的Redis客戶端依賴包Jedis:<dependency> <groupId>redis.clients</groupId

JAVA資料庫進行操作,實現資料庫中資料的插入,查詢,更改,刪除操作

轉載自:http://www.cnblogs.com/sodawoods-blogs/p/4415858.html (—)通過mysql workbench 建立一個數據庫,在這裡命名為company,然後建一個tb_employee表 (二)以下是java程式碼對錶

java 時間的操作

package com.mryt.cps.oms.center.util; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; i

MongoDB學習筆記(二) JAVAMongoDB的操作

 開發環境: System:Windows IDE:eclipse、MyEclipse 8 Database:mongoDB 開發依賴庫: JavaEE5、mongo-2.5.3.jar、junit-4.8.2.jar Email:[email p

Java 日期的各種操作

在Java中,操作日期主要涉及到一下幾個類: 1、java.util.Date         類 Date 表示特定的瞬間,精確到毫秒。從 JDK 1.1 開始,應該使用 Calendar 類實現日期和時間欄位之間轉換,使用 DateFormat 類來格式化和分析日期字串。Date 中的把日期解釋為