1. 程式人生 > >java之實現圖片二值化

java之實現圖片二值化

閒著沒事突然看到一部落格實現的圖片二值化 覺得intresting 就寫了個玩玩,所謂二值化 就是彩色照片變成黑白吧。。
影象的二值化,就是將影象上的畫素點的灰度值設定為0或255,也就是將整個影象呈現出明顯的只有黑和白的視覺效果
具體程式碼實現:

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

public class ImageTest {

    public static void main(String[] args) throws
Exception { //File.separator 而File.separator是系統預設的檔案分割符號,遮蔽了這些系統的區別。 //用File.separator保證了在任何系統下不會出錯。 String filename="D:"+ File.separator+"binaryzation"+File.separator+"wuyanzu.jpg"; File file = new File(filename); BufferedImage bufferedImage = ImageIO.read(file); int
height = bufferedImage.getHeight(); int width = bufferedImage.getWidth(); int rgb = bufferedImage.getRGB(0,0); int arr[][] =new int[width][height];//存放圖片每個畫素點的灰度值 // for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { arr[i][j] = getImageRgb(bufferedImage.getRGB(i,j)); } } // 構造一個型別為預定義影象型別之一的 BufferedImage,TYPE_BYTE_BINARY(表示一個不透明的以位元組打包的 1、2 或 4 點陣圖像。)
BufferedImage newBufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_BINARY); int threshold = 130;//閾值 關於閥值,網上有許多演算法,有興趣的朋友可以自己研究下,這裡我隨機給出了一箇中間數130。 for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { // 大於閥值則設為黑色,小於則為白色 if (getGray(arr,i,j,width,height)>threshold){ int black = new Color(255,255,255).getRGB(); newBufferedImage.setRGB(i,j,black); }else { int white = new Color(0,0,0).getRGB(); newBufferedImage.setRGB(i,j,white); } } } ImageIO.write(newBufferedImage,"jpg",new File("D:"+File.separator+"binaryzation"+File.separator+"binaryzation-wuyanzu.jpg")); System.out.println("圖片二值化成功"); //下面這段主要是實現加水印的功能 可忽略 int fontStyle=1; int fontSize=20;//字型大小 File pressFile =new File("D:/QRCodetest/pressText.txt"); String pressText = ReadFromFile.readFromFile(pressFile); String newImg="D:"+File.separator+"newPicWithPressText.jpg"; String targetImg="D:"+File.separator+"binaryzation"+File.separator+"binaryzation-wuyanzu.jpg"; QRCodeUtils.pressText(pressText,newImg,targetImg,fontStyle, Color.green,fontSize,width,height); } /** * //自己加周圍8個灰度值再除以9,算出其相對灰度值 * @param gray * @param x * @param y * @param width * @param height * @return */ private static int getGray(int[][] gray, int x, int y, int width, int height) { int rs = gray[x][y] +(x==0 ? 255 : gray[x-1][y]) +(x==0 || y==0 ? 255 : gray[x-1][y-1]) +(x==0 || y==height-1 ? 255 : gray[x-1][y+1]) +(y==0 ? 255 : gray[x][y-1]) +(y==height-1 ? 255 : gray[x][y+1]) +(x==width-1 ? 255 : gray[x+1][y]) +(x==width-1 || y==0 ?255: gray[x+1][y-1]) +(x==width-1 || y==height-1 ? 255 : gray[x+1][y+1]); return rs/9; } /** * 得到圖片灰度值 * @param rgb * @return */ private static int getImageRgb(int rgb) { //關於圖片的灰度值,這裡使用簡單的(R+G+B)/3 String argb = Integer.toHexString(rgb);//十進位制轉十六進位制 int r = Integer.parseInt(argb.substring(2,4),16);//16代表16進位制 int g = Integer.parseInt(argb.substring(4,6),16); int b = Integer.parseInt(argb.substring(6,8),16); int result = (int)((r+g+b)/3); return result; } }

效果如下:
檔案結構:

這裡寫圖片描述
原圖:
這裡寫圖片描述
二值化後:
這裡寫圖片描述
加水印:
這裡寫圖片描述