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

              由于研究的需要,博主使用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("小图片创建完成");   

	}
图像处理结果为:


达到了切分的效果!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值