由于研究的需要,博主使用java编写了对一张图片进行切分操作的程序,下面将编写的程序及遇到的问题进行描述:
最初的思想是先将图片横向切分,即定义一个矩形,其高为图片的高除以需要切分的个数,宽为源图片的宽,然后按照该矩形对图片进行切分,核心代码如下:
//将图片横向切分(从上往下)
public static void cropImage1(String srcPath,String toPath,
String readImageFormat,String writeImageFormat,int n) throws IOException{
if(n<1){
System.out.println("输入图片切分的个数有误,请重写输入!");
return;
}
BufferedImage bf=ImageIO.read(new File(srcPath));
int width=bf.getWidth();
int height=bf.getHeight();
int t=0;
FileInputStream fis = null ;
ImageInputStream iis =null ;
try{
//读取图片文件
fis = new FileInputStream(srcPath);
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(readImageFormat);
ImageReader reader = (ImageReader) it.next();
//获取图片流
iis = ImageIO.createImageInputStream(fis);
reader.setInput(iis,true) ;
//先对高是偶数的图片进行处理
if(height%n==0){
t=height/n;
//定义n个矩形
Rectangle []rects=new Rectangle[n];
for(int i=0;i<n;i++){
rects[i]=new Rectangle(0, i*t, width,t);
//Rectangle rect = new Rectangle(x, y, width, height);
//提供一个 BufferedImage,将其用作解码像素数据的目标。
//ImageReadParam []param = new ImageReadParam[n];
ImageReadParam param=reader.getDefaultReadParam();
param.setSourceRegion(rects[i]);
BufferedImage[] bi = new BufferedImage[n];
bi[i]=reader.read(0,param);
//BufferedImage bi = reader.read(0,param);
//保存新图片
File [] file=new File[n];
file[i]=new File(toPath+"\\"+i+"."+writeImageFormat);
ImageIO.write(bi[i], writeImageFormat, file[i]);
}
}
}finally{
if(fis!=null)
fis.close();
if(iis!=null)
iis.close();
}
设置图片切分粒度为2,运行该程序,得出切分图片的效果为:
其中第一幅图为原图,第二幅和第三幅为切分后的图,明显可以看出第三幅图切分后出现了问题,具体是由什么原因造成了,博主还没有找到答案,希望有知道原因的小伙伴不吝赐教。
在处理的过程中发现的另外一个问题是:在一张图像中,(0,0)坐标是在图像的左上角,往下是height的增方向,往右是weight的增方向,即在图像的右下角的坐标值是(height-1,weight-1),这跟传统意义上的坐标轴的方向是不一样的,这点需要特别注意。
查阅相关资料,得出以下代码可以正确完成图片的切分工作:
File file = new File("D:\\test1\\dog2.bmp"); // 项目目录下有名为btg.jpg的图片
FileInputStream fis = new FileInputStream(file);
BufferedImage image = ImageIO.read(fis); //把文件读到图片缓冲流中
int rows = 1; //定义图片要切分成多少块
int cols = 3;
int chunks = rows * cols;
int chunkWidth = image.getWidth() / cols; // 计算每一块小图片的高度和宽度
int chunkHeight = image.getHeight() / rows;
int count = 0;
BufferedImage imgs[] = new BufferedImage[chunks];
for (int x = 0; x < rows; x++) {
for (int y = 0; y < cols; y++) {
//初始化BufferedImage
imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());
//画出每一小块图片
Graphics2D gr = imgs[count++].createGraphics();
/**
* public abstract boolean drawImage(Image img,
int dx1,
int dy1,
int dx2,
int dy2,
int sx1,
int sy1,
int sx2,
int sy2,
ImageObserver observer)
img - 要绘制的指定图像。如果 img 为 null,则此方法不执行任何操作。
dx1 - 目标矩形第一个角的 x 坐标。
dy1 - 目标矩形第一个角的 y 坐标。
dx2 - 目标矩形第二个角的 x 坐标。
dy2 - 目标矩形第二个角的 y 坐标。
sx1 - 源矩形第一个角的 x 坐标。
sy1 - 源矩形第一个角的 y 坐标。
sx2 - 源矩形第二个角的 x 坐标。
sy2 - 源矩形第二个角的 y 坐标。
observer - 当缩放并转换了更多图像时要通知的对象。
*/
gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);
gr.dispose();
}
}
System.out.println("切分完成");
//保存小图片到文件中
for (int i = 0; i < imgs.length; i++) {
ImageIO.write(imgs[i], "bmp", new File("D:\\test1\\dog\\" + i + ".bmp"));
}
System.out.println("小图片创建完成");
}
图像处理结果为:
达到了切分的效果!