图片切割(java)

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;
 }


}

转载于:https://my.oschina.net/u/561475/blog/89158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值