需要注意的是:jimi提供了對幾乎所有圖片格式的解碼支持,但是為提供gif和tif/tiff格式的編碼api,gif編碼問題在網(wǎng)上可以找到縣相關(guān)的源碼,tiff好像jai:http://java./products/java-media/jai/index.jsp提供了它的編碼, 不過我沒有用jai,暫時用jpeg編碼代替了。
察看jimi的源碼,在com.sun.jimi.core中是jimi的核心處理api。
public void toJPG(String source, String dest, int quality) {
if (dest == null || dest.trim().equals("")) dest = source;
if (!dest.toLowerCase().trim().endsWith("jpg")) { dest += ".jpg"; System.out.println("Overriding to JPG, output file: " + dest); } if (quality < 0 || quality > 100 || (quality + "") == null || (quality + "").equals("")) { System.out.println("quality must between ’0’ and ’100’"); System.out.println("set to DEFAULT value:’75’"); quality = 75;
} try { JPGOptions options = new JPGOptions(); options.setQuality(quality); ImageProducer image = Jimi.getImageProducer(source); JimiWriter writer = Jimi.createJimiWriter(dest); writer.setSource(image); // 加入屬性設(shè)置,非必要 // /* writer.setOptions(options); // */ writer.putImage(dest); } catch (JimiException je) { System.err.println("Error: " + je); } } 在進(jìn)行格式轉(zhuǎn)換時,并不需要關(guān)心原圖的格式,只要要轉(zhuǎn)換的圖片格式在jimi的解碼格式范圍內(nèi),就可以完全透明的進(jìn)行decode過程:
ImageProducer image = Jimi.getImageProducer(source);
實(shí)際的解碼只需要以行代碼,就這么簡單。
編碼過程最簡單的也只需要很少的代碼:
JimiWriter writer = Jimi.createJimiWriter(dest); writer.setSource(image); // 加入屬性設(shè)置,非必要 // /* writer.setOptions(options); // */ writer.putImage(dest);
以上代碼就完成了圖片編碼到輸出到os生成轉(zhuǎn)換后文件的全過程。
上面代碼中的 writer.setOptions(options)是用來對輸出文件的屬性進(jìn)行相關(guān)的設(shè)置,每種格式的屬性都不一樣,com.sun.jimi.core.options.*中針對每種圖片編碼格式的相關(guān)屬性提供了getter和setter方法,可以方便的進(jìn)行設(shè)置:
com.sun.jimi.core.options.*中針對每種圖片編碼格式的相關(guān)屬性提供了getter和setter方法,可以方便的進(jìn)行設(shè)置:
JPGOptions options = new JPGOptions(); options.setQuality(quality);
格式轉(zhuǎn)換就這么簡單。
jimi不支持的encode格式的解決
/** * * @param source * @param dest * @throws JimiException */ public void toGIF(String source, String dest) throws JimiException { if (dest == null || dest.trim().equals("")) dest = source; // 1:轉(zhuǎn)換為jpg if (!dest.toLowerCase().trim().endsWith("jpg")) { dest += ".jpg"; } toJPG(source, dest, 75);
BufferedImage file_in = null; File file = new File(dest); try { file_in = javax.imageio.ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); }
int end = dest.lastIndexOf("."); file.deleteOnExit(); // output *.gif file.renameTo(new File(dest.substring(0, end) + ".gif")); // jpg to gif AnimatedGifEncoder e = new AnimatedGifEncoder(); e.start(dest); e.addFrame(file_in); e.finish(); } 這里用到了AnimatedGifEncoder 類,是我在網(wǎng)上搜索到的,對gif編碼提供了一個實(shí)現(xiàn),雖然還有待晚善的地方,不過單作格式轉(zhuǎn)關(guān)已經(jīng)夠用了:)
AnimatedGifEncoder e = new AnimatedGifEncoder(); e.start(dest); e.addFrame(file_in); e.finish();
需要注意的是:AnimatedGifEncoder 不能對所有格式的圖片正確的識別,所以先要將其他格式轉(zhuǎn)為jpg格式(最簡單的方法是用imageIO)
BufferedImage file_in = null; File file = new File(dest); try { file_in = javax.imageio.ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); }
這樣直接放入BufferedImage中就ok了
e.addFrame(file_in);
實(shí)際的編碼過程在上面這句完成。
int end = dest.lastIndexOf("."); file.deleteOnExit(); // output *.gif file.renameTo(new File(dest.substring(0, end) + ".gif"));
最后,在完成之前別忘了用上面幾句消滅證據(jù)喲:)
當(dāng)然這種方法其實(shí)并不好,最徹底的方法是修改AnimatedGifEncoder,不過做人涅要厚道壞?,毕竟蕛S思倚吹拇肼錚綣行巳さ吶笥芽梢蘊(yùn)致垡幌隆?br> 格式轉(zhuǎn)換解決了,縮放功能也就不算是問題了,以下代碼同時實(shí)現(xiàn)了格式轉(zhuǎn)關(guān)和線性縮放:
/** * * @param img * @param dest * @throws JimiException */ public void toTIF(Image img, String dest) throws JimiException { if (!dest.toLowerCase().trim().endsWith("tif")) { dest += ".tif"; System.out.println("Overriding to TIF, output file: " + dest); } dest = dest.substring(0, dest.lastIndexOf(".")) + ".jpg"; JimiWriter writer = Jimi.createJimiWriter(dest); writer.setSource(img); dest = dest.substring(0, dest.lastIndexOf(".")) + ".tif"; writer.putImage(dest); }
/** * 線性改變圖片尺寸(可同時改變圖片格式) * * @param source * 源文件完整路徑 * @param desc * 目標(biāo)文件完整路徑 * @param ins * 放大/縮小比率 * @throws JimiException * @throws IOException */ public void changeDimension(String source, String desc, double ins) throws JimiException, IOException { String temp = desc; File _file = null; if (desc == null || desc.trim().equals("")) desc = source; if (!desc.toLowerCase().trim().endsWith("jpg")) { temp = desc.trim() + ".jpg"; } this.toJPG(source, temp, 75); _file = new File(temp); // 讀入文件
Image src = javax.imageio.ImageIO.read(_file); // 構(gòu)造Image對象 double wideth = (double) src.getWidth(null); // 得到源圖寬 double height = (double) src.getHeight(null); // 得到源圖長 int iWideth = (int) (wideth * ins); int iHeight = (int) (height * ins); BufferedImage tag = new BufferedImage(iWideth, iHeight, BufferedImage.TYPE_INT_RGB); tag.getGraphics().drawImage(src, 0, 0, iWideth, iHeight, null); // 繪制縮小后的圖
if (!temp.trim().equals(desc)) _file.deleteOnExit();
if (desc.toLowerCase().trim().endsWith("gif")) { AnimatedGifEncoder e = new AnimatedGifEncoder(); e.start(desc); e.addFrame(tag); e.finish(); } else if (desc.toLowerCase().trim().endsWith("tif") || desc.toLowerCase().trim().endsWith("tiff")) { this.toTIF(tag, desc); } else { JimiWriter writer = Jimi.createJimiWriter(desc); writer.setSource(tag); writer.putImage(desc); } }
BufferedImage的構(gòu)造函數(shù)中的參數(shù)類型為int,所以以上代碼在改變圖象尺寸時稍有偏差,不過簡單演示一下還是可以的。
jimi的example中可以找到很多單項(xiàng)圖片處理功能的demo,有時間可以研究一下,會有不少收獲的。
|