Java图片读取之BufferedImage得到像素矩阵的两种方式
2016-12-29 16:19
204 查看
最近在尝试着采用Java在图像处理领域实践一下常用的机器学习算法。首先涉及到的是如何将一副图片读取到一个像素矩阵中(Java中就是一维或二维数组中)。在实践过程中,通过测试代码,我发现基于BufferedImage可以有两种获取像素矩阵的方式,但需要注意像素点的保存顺序问题。
具体表现在:本例中的图片是一副彩色图片(博客头像),大小为425*292,即宽度(Width)为425,高度(Height)为292。
放上测试代码(刚测试完就放上来了,不要纠结细节),后面再说明:
在方式一中,getRGB()方法,根据手册,其返回的int型数据(32位)为ARGB格式,其中ARGB各占8bit。getRGB的两个参数x,y分别对应像素点的横纵坐标,但需注意的是,以图片左上角点为坐标原点,x轴正方向是沿着width方向的,y轴正方向是沿着Height方向的。不信的同学,可以试着把二者调换,就会发现系统会报数组溢出的异常。
在方式二中,像素会通过getPixels()方法被保存在一个一维数组中。其中temp数据为读取数据的缓冲区,其大小的确定一定要是其图像通道数(通过getNumBands()获得)的整数倍,例如这里的彩色图片有RGB三个通道,所以通道数就为3。在最终得到的结果一维数组中,一维数组的大小为Width*Height*NumBands。此处,一个像素点占三个位置(R,G,B),与方式一得到的值作比对时,才发现,这里的一维数组中,像素点的排列顺序是按着Width横向扫码得到的。
鉴于操作的便捷来说,个人肯定偏向于方向一,首先它把RGB值整合到了一起,不像方式二中是分开的三个int数,二是二维数组相较于一维数组,肯定更加接近矩阵的概念,便于运算。
具体表现在:本例中的图片是一副彩色图片(博客头像),大小为425*292,即宽度(Width)为425,高度(Height)为292。
放上测试代码(刚测试完就放上来了,不要纠结细节),后面再说明:
/** * Created by Song on 2016/12/29. * 用于读取Image文件 */ public final class ImgHandler { public static void getData(String path){ try{ BufferedImage bimg = ImageIO.read(new File(path)); int [][] data = new int[bimg.getWidth()][bimg.getHeight()]; //方式一:通过getRGB()方式获得像素矩阵 //此方式为沿Height方向扫描 for(int i=0;i<bimg.getWidth();i++){ for(int j=0;j<bimg.getHeight();j++){ data[i][j]=bimg.getRGB(i,j); //输出一列数据比对 if(i==0) System.out.printf("%x\t",data[i][j]); } } Raster raster = bimg.getData(); System.out.println(""); int [] temp = new int[raster.getWidth()*raster.getHeight()*raster.getNumBands()]; //方式二:通过getPixels()方式获得像素矩阵 //此方式为沿Width方向扫描 int [] pixels = raster.getPixels(0,0,raster.getWidth(),raster.getHeight(),temp); for (int i=0;i<pixels.length;) { //输出一列数据比对 if((i%raster.getWidth()*raster.getNumBands())==0) System.out.printf("ff%x%x%x\t",pixels[i],pixels[i+1],pixels[i+2]); i+=3; } }catch (IOException e){ e.printStackTrace(); } } public static void main(String [] args){ getData("E:\\a.jpg"); } }
在方式一中,getRGB()方法,根据手册,其返回的int型数据(32位)为ARGB格式,其中ARGB各占8bit。getRGB的两个参数x,y分别对应像素点的横纵坐标,但需注意的是,以图片左上角点为坐标原点,x轴正方向是沿着width方向的,y轴正方向是沿着Height方向的。不信的同学,可以试着把二者调换,就会发现系统会报数组溢出的异常。
在方式二中,像素会通过getPixels()方法被保存在一个一维数组中。其中temp数据为读取数据的缓冲区,其大小的确定一定要是其图像通道数(通过getNumBands()获得)的整数倍,例如这里的彩色图片有RGB三个通道,所以通道数就为3。在最终得到的结果一维数组中,一维数组的大小为Width*Height*NumBands。此处,一个像素点占三个位置(R,G,B),与方式一得到的值作比对时,才发现,这里的一维数组中,像素点的排列顺序是按着Width横向扫码得到的。
鉴于操作的便捷来说,个人肯定偏向于方向一,首先它把RGB值整合到了一起,不像方式二中是分开的三个int数,二是二维数组相较于一维数组,肯定更加接近矩阵的概念,便于运算。
相关文章推荐
- java 实现BufferedImage和ImageReader两种方式获取图片宽高、判断图片类型、获取图片大小工具类代码以及测试响应结果
- 获取图片、屏幕像素并纠正bufferedimage导入失败的问题Ps:手机端android的图片和屏幕像素获取正确方式
- Atitit.java图片图像处理attilax总结 BufferedImage extends java.awt.Image获取图像像素点image.getRGB(i, lineIndex); 图片剪辑/AtiPlatf_cms/src/com/attilax/img/imgx.javacutImage图片处理titit 判断判断一张图片是否包含另一张小图片 atitit 图片去噪算法的原理与
- java读取图片三种方式
- Java读取图片的三种方式
- JavaWeb读取配置文件路径的两种方式
- java BufferedImage 合成多张图片
- java读取远程url图片,得到宽高
- java读取图片三种方式总结
- 用java读取图片的三种方式
- JAVA中properties配置文件的两种读取方式
- java中两种select方式,,一种从数据表中读取
- 从图片文件或BufferedImage中得到InputStream
- java中ImageIO.write(bufferedImage输出图片时,图片的改变问题
- java读取远程url图片,得到宽高
- java开发_比较使用ImageReader和BufferedImage获取图片尺寸总结
- JAVA各层怎样读取资源文件(servletContext和classloader两种方式)
- java 剪切 图片 BufferedImage
- Java读取图片像素和大小
- Java读取图片并修改像素,创建图片