BufferedImage是Image的一個子類,BufferedImage生成的圖片在內存里有一個圖像緩沖區,利用這個緩沖區我們可以很方便的操作這個圖片,通常用來做圖片修改操作如大小變換、圖片變灰、設置圖片透明或不透明等。
BufferedImage bufferedImage = ImageIO.read(new FileInputStream(filePath));
使圖片變灰
使圖片變灰有兩種方法,一種是使用現成的類,一種是自己對每個像素進行操縱。
使用現成的類ColorConvertOp,它的作用就是將一個顏色模式的圖片轉換為另一個顏色模式的圖片。顏色模式是諸如RGB顏色模式、灰度顏色模式等決定圖片色彩的東西,比如一副RGB顏色模式的圖片是彩色,但我們把它復制到一個灰度顏色模式的圖片上時,圖片就成灰色的了。
public BufferedImage getGrayPicture(BufferedImage originalImage) { BufferedImage grayPicture; int imageWidth = originalImage.getWidth(); int imageHeight = originalImage.getHeight(); grayPicture = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_3BYTE_BGR); ColorConvertOp cco = new ColorConvertOp(ColorSpace .getInstance(ColorSpace.CS_GRAY), null); cco.filter(originalImage, grayPicture); return grayPicture; }
自己操縱圖片的像素實現圖片變灰。圖片變灰的通用算法:取出某個像素的r、g、b值,然后重新計算r、g、b值,計算公式為r=r*0.3+g*0.59+b*0.11,g=r,b=g,最后將該rgb值重新寫回像素。
可以用下面三個函數
分別取出r、g、b。ColorModel是一個用來將圖片某點的rgb值轉化為r、g、b以及alpha等值的類。而bufferedImage本身只能取出一個完整的rgb值,無法分離單獨的r、g、b等值。
bufferedImage.getColorModel().getRed(int pixel)
bufferedImage.getColorModel().getGreen(int pixel)
bufferedImage.getColorModel().getBlue(int pixel)
但是這里要注意的是使用這種方法取出r、g、b時,有可能彈出一個錯誤信息——IllegalArgumentException: More than one component per pixel。通常當你使用這個方法操縱jpg等格式的圖片時會報這個錯誤。這是因為某些圖片如JPG格式的不支持使用單個int值的像素讀取rgb等信息,應該使用Object類型的像素值進行讀取,也就是bufferedImage.getColorModel().getGreen(Object indata)
public BufferedImage getGrayPicture(BufferedImage originalImage) { int green=0,red=0,blue=0,rgb; int imageWidth = originalImage.getWidth(); int imageHeight = originalImage.getHeight(); for(int i = originalImage.getMinX();i < imageWidth ;i++) { for(int j = originalImage.getMinY();j < imageHeight ;j++) { //圖片的像素點其實是個矩陣,這里利用兩個for循環來對每個像素進行操作 Object data = routeImage.getRaster().getDataElements(i, j, null);//獲取該點像素,並以object類型表示 red = routeImage.getColorModel().getRed(data); blue = routeImage.getColorModel().getBlue(data); green = routeImage.getColorModel().getGreen(data); red = (red*3 + green*6 + blue*1)/10; green = red; blue = green; /* 這里將r、g、b再轉化為rgb值,因為bufferedImage沒有提供設置單個顏色的方法,只能設置rgb。rgb最大為8388608,當大於這個值時,應減去255*255*255即16777216 */ rgb = (red*256 + green)*256+blue; if(rgb>8388608) { rgb = rgb - 16777216; } //將rgb值寫回圖片 routeImage.setRGB(i, j, rgb); } } return originalImage; }