使用java对图像进行切分的程序及注意事项

来源:互联网 发布:java ssh开源项目 编辑:程序博客网 时间:2024/06/06 08:55

              由于研究的需要,博主使用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("小图片创建完成");   }
图像处理结果为:


达到了切分的效果!

0 0