相信大家平時碰到過一些在JAVA中對圖像進行處理的需求,比如需要對上傳的圖片加上自己的簽名或圖標,或者生成和解析動態的GIF圖片,以及處理PSD文件圖像信息。本文就JAVA在圖像處理中一些基本應用進行了介紹。希望通過能夠對大家在以後的圖像處理中有些幫助。 一、對一個現有的圖片進行文字和圖標的合成
我們先從下面的這段簡單的代碼開始
import java.awt.*; import javax.imageio.ImageIO; import java.awt.image.*; import java.io.*; import com.sun.image.codec.jpeg.*; /** * @author Anders.Hu * 2005-01-12 */ public class Test { public static void main(String[] args) { try { //讀取模板圖片內容 BufferedImage image = ImageIO.read(new FileInputStream("c://1.jpg")); Graphics2D g = image.createGraphics();//得到圖形上下文 g.setColor(Color.BLACK); //設置畫筆顏色 //設置字體 g.setFont(new Font("宋體", Font.LAYOUT_LEFT_TO_RIGHT, 15));//寫入簽名 g.drawString("很好吃誒,要不要也來一口?",43, image.getHeight() - 10); g.dispose(); FileOutputStream out = new FileOutputStream("c://2.jpg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(image); out.close(); } catch(Exception e) { e.printStackTrace(); } } }
相信大家看到這裏已經知道了大致的操作過程,我想我還是在這裏把基本的原理簡單說明一下便於對後續內容的闡述:首先我們通過javax.imageio.ImageIO的read方法讀取圖像在BufferedImage中,然後我們可以通過BufferedImage的createGraphics方法取得圖像的上下文便於對圖像的處理,如加上自己喜愛的文字或圖片等,最後調用JPEGCodec的encode方法進行JPEG編碼,然後就是保存到文件中了。
需要提出的是JPEGCodec是非標準類,如果程序是運行JDK1.4以上版本的話,可以採取以下代碼進行JPEG編碼: ImageIO.write(image, "JPEG", out);
可能在你的實際需求還要加入一些圖標的修飾,要做到這一步,我們只需要在上面的代碼中利用Graphics2D的drawImage方法做到。下面是加入圖標的代碼
public static void main(String[] args) { try { BufferedImage image = ImageIO.read(new FileInputStream("c://1.jpg")); //讀取圖標 BufferedImage image_biao = ImageIO.read(new FileInputStream("c://i.jpg")); Graphics2D g = image.createGraphics(); g.setColor(Color.YELLOW); g.setFont(new Font("宋體", Font.LAYOUT_LEFT_TO_RIGHT, 25)); g.drawString("很好吃誒,要不要也來一口?",43, image.getHeight() - 80); //寫入圖標 g.drawImage(image_biao, 20,image.getHeight() - 80, image_biao.getWidth(null), image_biao.getHeight(null), null); g.dispose(); FileOutputStream out = new FileOutputStream("c://3.jpg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(image); out.close(); } catch(Exception e) { e.printStackTrace(); } } 二、生成和解析動態的GIF圖片 有了以上對圖象的基本處理之後,我們再來看看對動態GIF圖片的處理。 GIF是一種由CompuServe創建的壓縮和傳送圖像文件的格式。 GIF圖像是基於顏色列表的(存儲的數據是該點的顏色對應於顏色列表的索引值),最多隻支持8位(256色)。GIF文件內部分成許多存儲塊,用來存儲多幅圖像(Frame)或者是決定圖像表現行爲的控制塊,用以實現動畫和交互式應用。因此我們要生成和分析GIF圖像的話,就需要對GIF文件格式進行分析,這裏我們採用網上的一個開源代碼進行處理。 先在http://www.fmsware.com/stuff/gif.zip 下載處理GIF圖片的代碼,解壓之後可以發現有AnimatedGifEncoder.java, GifDecoder.java, LZWEncoder.java,NeuQuant.java這4個JAVA文件,在這些文件的開頭都已經有了簡單的說明。其中AnimatedGifEncoder.是用來生成GIF文件的類,而GifDecoder則是用來解析GIF動態圖像Frame信息的類。LZWEncoder是LZW壓縮算法類,NeuQuant是用來生成顏色列表的類。 把它們加入到我們的項目文件中,然後我們就來利用AnimatedGifEncoder來寫一段合成動態GIF文件的代碼。
import java.io.FileInputStream; import javax.imageio.ImageIO; import open.AnimatedGifEncoder; /** * @author Anders.Hu * 2005-01-13 */ public class TestMakeGIF { public static void main(String[] args) { try { //指定Frame的文件 String imgFileName[] = new String[]{"c://1.jpg","c://2.jpg", "c://3.jpg"}; String outputFileName = "c://test.gif"; AnimatedGifEncoder e = new AnimatedGifEncoder(); e.start(outputFileName);//開始處理 e.setDelay(500); //設置延遲時間 for (int i = 0; i < imgFileName.length; i++) { e.addFrame(ImageIO.read(new FileInputStream(imgFileName[i])));//加入Frame } e.finish(); } catch (Exception e) { e.printStackTrace(); } }
代碼運行的結果如下 是不是覺得有了這個AnimatedGifEncoder類,合成GIF文件挺方便的,現在我們再來看看GifDecoder的使用。
public class TestGifDecoder { public static void main(String[] args) { try { String inputFileName = "c://test.gif"; GifDecoder decoder = new GifDecoder(); decoder.read(inputFileName); int n = decoder.getFrameCount();//得到frame的個數 for (int i = 0; i < n; i++) { BufferedImage frame = decoder.getFrame(i); //得到frame int delay = decoder.getDelay(i);//得到延遲時間 //生成JPG文件 String outFilePath = "c://test_"+i+".jpg"; FileOutputStream out = new FileOutputStream(outFilePath); ImageIO.write(frame,"jpeg",out); } } catch (Exception e) { e.printStackTrace(); } } }
代碼運行完畢之後,就可以生成了相應的4個jpg文件。 對於以上的代碼有下面幾點需要補充: 1. 我測試過使用BMP文件的情況,但是沒有通過代碼的測試,可能是在把BMP圖像轉爲256色圖像時出現了錯誤。所以在使用之前還需要用其他工具把BMP文件轉爲JPG格式。 2. 在合成GIF文件的AnimatedGifEncoder類中有下面幾個值得關注的函數 2.1:setFrameRate(float)每秒種播放的幀數 2.2:setQuality(int quality) 設置在GIF規範中轉換爲256位圖像時的質量參數這個值設置的越小,質量越高,但速度越慢,反之依然,不過超過20以後,速度不會有明顯的提升,默認爲10。 2.3:setSize(int x,int y) 設置GIF圖像的大小,默認值爲第一個加入的幀的圖像的大小。
三、對PSD圖像文件的分析 我們先用PS對模板圖片加上一串字符,保存爲TestPsd.psd,注意保存時不要合併圖層。然後從http://www.fmsware.com/stuff/PSDReader.java 下載一個分析PSD代碼的JAVA文件,並加入到我們的項目中。 並運行下面的代碼
import java.awt.Point; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import open.PSDReader; import com.sun.image.codec.jpeg.*; /** * @author Ander.Hu * 2005-10-13 */ public class TestPsd { public static void main(String[] args) { try { PSDReader r = new PSDReader(); r.read("c://testPsd.psd"); int n = r.getFrameCount(); for (int i = 0; i < n; i++) { BufferedImage image = r.getLayer(i); Point offset = r.getLayerOffset(i); //生成JPG文件 String outFilePath = "c://testPsd_"+i+".jpg"; FileOutputStream out = new FileOutputStream(outFilePath); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(image); } } catch(Exception e) { e.printStackTrace(); } } }
此時我們便可以發現3個解析後的JPG文件,因爲包括背景圖層在內有3個圖層,故有3個JPG文件。 目前PSDReader 類只支持沒有壓縮過的或者使用RLE壓縮的RGB文件,並且也不支持PS3.0以上的特殊功能。 總結 在JAVA對圖像的處理過程中,通常基本步驟是通過讀取圖像信息到圖像緩衝中->同時取得圖形上下文->對圖像進行相應的處理->生成圖像文件。
|