import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; /** * @author hst-wlm * */ public class Image { private String imgDir; // 處理圖片的路徑 private int width; // 原始圖片的寬度 private int height; // 原始圖片的高度 private int countHeight[]; // 豎座標上分割點的個數 private int countWidth[]; // 橫座標上分割點的個數 private int rBound[]; private int gBound[]; private int bBound[]; public Image(String imgDir) { this.imgDir = imgDir; rBound = new int[2]; gBound = new int[2]; bBound = new int[2]; } /* * 初始化操做 */ private BufferedImage init() { File file = new File(getImgDir()); if (!file.exists()) { return null; } BufferedImage bufImg = null; try { bufImg = ImageIO.read(file); } catch (Exception e) { e.printStackTrace(); } int height = bufImg.getHeight(); int width = bufImg.getWidth(); countHeight = new int[height]; countWidth = new int[width]; this.setWidth(width); this.setHeight(height); return bufImg; } /** * 功能說明: 切割圖片 * * @param cutDirection * 切割方向 * @param scale * 像素點跟相對與寬度或者高度的倍數 * @return */ public String cutBigImg(boolean cutDirection, float scale) throws IOException { BufferedImage bufImg = init(); if (null == bufImg) { return "處理失敗!"; } scanImgForGetCountHW(width, height, bufImg, cutDirection); Map<Integer, Integer> mapLine; mapLine = getImgSplitLine(cutDirection, scale); // for (int i = 1; i <= mapLine.size(); i++) { // System.out.println("mapline " + mapLine.get(i)); // } if (null == mapLine) { return "處理失敗!"; } outputProcessedImg(bufImg, mapLine, cutDirection); return "切割成功!"; } /** * 功能說明: 取得圖片橫向或者縱向上的點數 * * @param width * 圖片的寬度 * @param height * 圖片高度 * @param bufImg * 圖片在內存的緩存 * @param scanDirection * true:按橫向掃描 false:按縱向掃描 * @return */ private int[][] scanImgForGetCountHW(int width, int height, BufferedImage bufImg, boolean scanDirection) { int result[][] = new int[width][height]; int innerMax; int outerMax; if (scanDirection) { innerMax = width; outerMax = height; } else { innerMax = height; outerMax = width; } // 將在範圍內的點存入數組中 for (int i = 0; i < outerMax; i++) { for (int j = 0; j < innerMax; j++) { // 去除alpha通道的值即透明度的份量 if (scanDirection) { int pixel = bufImg.getRGB(j, i) & 0xFFFFFF; result[j][i] = pixel; if (getRGBBoolean(pixel)) { countHeight[i] += 1; } } else { int pixel = bufImg.getRGB(i, j) & 0xFFFFFF; result[i][j] = pixel; if (getRGBBoolean(pixel)) { countWidth[i] += 1; } } } } return result; } /** * * @param pixel * 像素值 * * @return 若是該像素在範圍內怎返回true,不然返回false。 */ private boolean getRGBBoolean(int pixel) { int[] rgb = new int[3]; rgb[0] = (pixel & 0xff0000) >> 16; rgb[1] = (pixel & 0xff00) >> 8; rgb[2] = (pixel & 0xff); // System.out.println("rgb 1: "+rgb[0]+" 2: "+rgb[1]+" 3: "+rgb[2]); return (rgb[0] > rBound[0] && rgb[0] < rBound[1] && rgb[1] > gBound[0] && rgb[1] < gBound[1] && rgb[2] > bBound[0] && rgb[2] < bBound[1]); } /** * 功能說明: 設置所取邊界的rgb各個份量的範圍 * * @param rLower * 紅色下界 * @param rUpper * 紅色上界 * @param gLower * 綠色下界 * @param gUpper * 綠色上界 * @param bLower * 藍色下界 * @param bUpper * 藍色上界 */ public void setCloseColorRGB(int rLower, int rUpper, int gLower, int gUpper, int bLower, int bUpper) { rBound[0] = rLower; rBound[1] = rUpper; gBound[0] = gLower; gBound[1] = gUpper; bBound[0] = bLower; bBound[1] = bUpper; } /** * 功能說明: 獲取圖片的切割線 * * @param lineDirection * true:取得每行匹配的像素數,false:取得每列匹配的像素數 * @param scale * scale的值小於1大於0 * @return */ private Map<Integer, Integer> getImgSplitLine(boolean lineDirection, float scale) { Map<Integer, Integer> mapLine = new HashMap<Integer, Integer>(); int preheight = 0, maxcount = 0, cnt = 0, length, boundary; int count[]; if (lineDirection) { length = countHeight.length; count = countHeight; boundary = (int) (width * scale); } else { length = countWidth.length; count = countWidth; boundary = (int) (height * scale); } // System.out.println("boundary : "+boundary); // 剔除相鄰的邊界點,Map中存放的是能夠作爲邊界區分的點 for (int i = 1; i < length; i++) { // System.out.println("count :"+count[i]); if (count[i] > boundary) { if (preheight == i - 1) { if (count[i] > maxcount) { mapLine.put(cnt, i); maxcount = count[i]; } } else { cnt++; // System.out.println("i : "+i); mapLine.put(cnt, i); maxcount = count[i]; } preheight = i; } } return mapLine; } /** * 功能說明: 根據切割點,切割圖片 * * @param srcImg * 原圖buff * @param mapLine * 切割線 * @throws IOException */ private void outputProcessedImg(BufferedImage srcImg, Map<Integer, Integer> mapLine, boolean direction) throws IOException { BufferedImage image = null; String fileName; File subfile; for (int i = 1; i <= mapLine.size(); i++) { if (i == 1) { if (direction) { image = srcImg.getSubimage(0, 0, width, (int) mapLine.get(i)); } else { image = srcImg.getSubimage(0, 0, (int) mapLine.get(i), height); } fileName = "H:\\ocr\\" + "map_" + i + ".jpg"; subfile = new File(fileName); ImageIO.write(image, "JPEG", subfile); } else { int y = (int) mapLine.get(i - 1); int hei = mapLine.get(i) - mapLine.get(i - 1); if (direction) { image = srcImg.getSubimage(0, y, width, hei); } else { image = srcImg.getSubimage(y, 0, hei, height); } fileName = "H:\\ocr\\" + "map_" + i + ".jpg"; subfile = new File(fileName); ImageIO.write(image, "JPEG", subfile); } } } public String getImgDir() { return imgDir; } public void setImgDir(String imgDir) { this.imgDir = imgDir; } 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; } }