使用java对图像进行切分的程序及注意事项
2016-08-30 17:18
543 查看
由于研究的需要,博主使用java编写了对一张图片进行切分操作的程序,下面将编写的程序及遇到的问题进行描述:
最初的思想是先将图片横向切分,即定义一个矩形,其高为图片的高除以需要切分的个数,宽为源图片的宽,然后按照该矩形对图片进行切分,核心代码如下:
其中第一幅图为原图,第二幅和第三幅为切分后的图,明显可以看出第三幅图切分后出现了问题,具体是由什么原因造成了,博主还没有找到答案,希望有知道原因的小伙伴不吝赐教。
在处理的过程中发现的另外一个问题是:在一张图像中,(0,0)坐标是在图像的左上角,往下是height的增方向,往右是weight的增方向,即在图像的右下角的坐标值是(height-1,weight-1),这跟传统意义上的坐标轴的方向是不一样的,这点需要特别注意。
查阅相关资料,得出以下代码可以正确完成图片的切分工作:
达到了切分的效果!
最初的思想是先将图片横向切分,即定义一个矩形,其高为图片的高除以需要切分的个数,宽为源图片的宽,然后按照该矩形对图片进行切分,核心代码如下:
//将图片横向切分(从上往下) 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 ; 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 ; ImageReadParam param=reader.getDefaultReadParam(); param.setSourceRegion(rects[i]); BufferedImage[] bi = new BufferedImage ; bi[i]=reader.read(0,param); //BufferedImage bi = reader.read(0,param); //保存新图片 File [] file=new File ; 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("小图片创建完成"); }图像处理结果为:
达到了切分的效果!
相关文章推荐
- Java中使用JSON进行parse操作时一个重要的注意事项
- Java高并发程序-Chapter5 锁的优化及注意事项(第三十三讲)无锁 - 无锁类的使用
- 使用 WebSphere Studio Application Developer 开发 Java 程序: 与 VisualAge for Java 进行比较
- 讲解关于编写跨平台Java程序时的注意事项
- 使用 Java 进行图像处理 - 图像裁剪
- Domino使用Java代理的注意事项
- 跨平台Java程序注意事项
- 编写跨平台Java程序注意事项
- 编写跨平台Java程序注意事项
- 使用 Java 进行图像处理 - 图像翻转
- 编写跨平台Java程序注意事项
- 编写跨平台Java程序注意事项
- 编写跨平台Java程序注意事项
- 编写跨平台Java程序注意事项
- 使用.net框架应用C#语言开发窗口程序的一些注意事项
- 编写跨平台Java程序注意事项
- 关于Java开发中使用Oracle数据库的一点注意事项
- 使用 Java 进行图像处理 - 取得图像上指定位置像素的 rgb 颜色分量
- java-编写跨平台Java程序注意事项
- 编写跨平台Java程序注意事项