曾几何时,Java图像处理已经被认为是太过鸡肋,就连Java的创始公司,在java图像处理方面也是浅尝辄止,可能相比较C++,Java在这方面的处理,确实差强人意。

不过Java类库中有一个叫JAI的库,全程是java advanced image—Java高级预想处理,其实个人觉得这个库非常丰富,奈何JAI只发行了2个版本就停止维护了,

到现在也没有找到源码,资料更是少的可怜。鉴于上述原因,本人将开始记录JAI以及Java 二维图像相关知识,本文主要介绍Java图像的主要类以及图像基础知识。

  Java中我们对图像的操纵一般使用BufferImage,比如我们一般会使用一下方法,将一个图片文件读取到bufferimage

BufferedImage image = ImageIO.read(new File("D:\\Gis开发\\数据\\影像数据\\tiff\\china.tif"));

这个是将已经存在的图片文件,读取到BufferedImage中,其实大家都知道图像之所以会呈现出各种颜色,无外乎就是像素值、颜色模型、样本模型这三个重要参数来体现的。其实Java的图像类

BufferedImage也无外乎这三个重要参数。
比如我们通过BufferedImage构造参数就可以发现,其中一个构造参数是
public BufferedImage (ColorModel cm,
WritableRaster raster,
boolean isRasterPremultiplied,
Hashtable<?,?> properties)

这个构造参数中,ColorModel是颜色模型,raster是栅格数据,它是由像素值和样本模型构成的,这个我们可以通过它的构造函数看到

protected WritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Point origin)

其中sampleModel是样例模型,dataBuffer是像素值数组。

下面介绍以上三个要素:

  • ColorModel

Java中ColorModel的实现类主要有ComponentColorModel、IndexColorModel等,我们先来看看ComponentColorModel构造函数

public ComponentColorModel (ColorSpace colorSpace,
boolean hasAlpha,
boolean isAlphaPremultiplied,
int transparency,
int transferType)

其中colorSpace很重要,颜色空间其实决定了最终这些像素值是如何呈现在我们硬件上的,比如我们的电脑显示器,印刷等。

比如常见以下颜色空间:

RGB彩色模型
@Native public static final int TYPE_RGB = 5;
灰度模型
@Native public static final int TYPE_GRAY = 6
CMYK彩色模型
@Native public static final int TYPE_CMYK = 9;

比如我们通常的彩色图是用 TYPE_RGB,创建灰度图用TYPE_GRAY,以及TYPE_CMYK颜色模型。

hasAlpha:是否有透明通道,比如常见的png(32),就有alpha通道

isAlphaPremultiplied:

transparency:  透明类型    其中1表示完全不透明  2表示完全透明或不透明  3表示介于两者之间,也就是透明度可调(一般选择3)

transferType:

  • SampleModel
Java中sampleModel的实现类主要有ComponentSampleModel以及它的子类PixelInterleavedSampleModel,我们来看看它的构造函数
public ComponentSampleModel(int dataType,
int w, int h,
int pixelStride,
int scanlineStride,int bandOffsets[])

其中datatype:数据类型,即就是像素值的表示单位,比如常见的RGB三通道,使用TYPE_BYTE来表示,即就是每个通道8位,用0-255来表示,常见的DEM地形数据,也会直接使用TYPE_SHORT或者TYPE_FLOAT来定义。

w:  图片宽度

h:  图片高度

pixelStride:像素步幅,其实就是我们的像素在宽和高方向的间隔设置,通常设置为1,表示每个像素都会填充一个值,如果设置为2,则表示每2个位置设置一个像素值,这样其中的databuffer数组就会相应的缩减。

scanlineStride:  线性步幅,如果pixelStride为1,则scanlineStride为width。

bandOffsets:波段偏移量,一般都是0,比如RGB数据,一般都是new int[] {0,0,0}

  • 像素值

像素值其实就是表示颜色的数字,这里提示一点,比如RGB数据,如果数据类型是TYPE_BYTE,如果图片是10x10大小,则这个DataBufferByte的数组大小就是10*10*3。

下面我们来自定义一个图片:

byte[] rasterBuffer = new byte[10*10*3];
DataBufferByte dataBuffer = new DataBufferByte(rasterBuffer, 10*10*3);
ColorSpace space = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ComponentSampleModel sampleModle = new ComponentSampleModel(DataBuffer.TYPE_BYTE,10, 10, 1, 10*3, new int[] {0,1,2});
int[] bits = {8,8,8};
ComponentColorModel colorModel = new ComponentColorModel(space, bits, false, false, Transparency.TRANSLUCENT,DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createWritableRaster(sampleModle,dataBuffer,new Point(0,0));
BufferedImage image = new BufferedImage(colorModel,raster,false,null);

其实在日常开发中,我们经常会遇到ComponentColorModel,但是偶尔也会遇到IndexColorModel,这两个颜色模型有什么区别呢?

自己找了一个这样的数据,解析后发现,如下操作

从这个输出可以看出,图像的是IndexColorModel和普通ComponentColorModel是一样的,唯一不同的是rgb的数组大小不一样,下面我们来看看对应的samplemodel

可以看出虽然colorModel有3通道,但实际samplemodel的band只有一个,也就是说实际只有一个samplebands

这也就解是了原本按照三通道的样本,该数据的databuffer应该是7162*5968*3    而实际它的databuffer的size只有

7162*5968,也就是上图中的data的size大小,这跟我们平时看到的ComponentColorModel的data不一样,也就是用一位byte就表示了三个通道的颜色分量。

 扩展

一般对于图像显示而言,我们拿到每个通道的颜色分量,其实还是需要转为显示器等输出设备可以识别的,这个我们可以通过ColorModel的

getRGB()方法,我们来看下这个方法
public int getRGB(int pixel) {
if (numComponents > 1) {
throw new
IllegalArgumentException("More than one component per pixel");
}
if (signed) {
throw new
IllegalArgumentException("Component value is signed");
}

return (getAlpha(pixel) << 24)
| (getRed(pixel) << 16)
| (getGreen(pixel) << 8)
| (getBlue(pixel) << 0);
}

可以看出是通过三通道的分量的位运算获得最后的像素值,而IndexColorModel的getRGB()我们来看下

final public int getRGB(int pixel) {
return rgb[pixel & pixel_mask];
}

明显只有一个像素来计算最后的整数像素值。

总结

      好了今天就简单介绍Java图像处理的基础操作,后续还将持续介绍一些实用的图像处理方法,下一篇将介绍Java中图像的放射变换,欢迎大家持续关注。




Java 图像处理(一)的更多相关文章

  1. Java 图像处理框架-Marvin

    网上看到,摘录过来的,暂时还没涉足这方面的东西 Marvin 1.4.5 的插件接口支持处理多个图像作为输入,新的插件可通过多个图片来确认背景,新的插件可使用多个图片来合并相同场景. Marvin 是 ...

  2. Java图像处理最快技术:ImageJ 学习第一篇

    ImageJ是世界上最快的纯Java的图像处理程序. 它能够过滤一个2048x2048的图像在0.1秒内(*). 这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Ima ...

  3. Atitit. 图像处理jpg图片的压缩 清理垃圾图片 java版本

    Atitit. 图像处理jpg图片的压缩  清理垃圾图片 java版本 1. 清理图片压缩图片尺寸 1 2. 所以要使用ImageWriter 1 3. Thumbnails质量压缩builder.o ...

  4. atitit.验证码识别step3----去除边框---- 图像处理类库 attilax总结java版本

    atitit.验证码识别step3----去除边框---- 图像处理类库 attilax总结java版本 1. 去除边框思路原理 1 2. Thumbnailator 是一个用来生成图像缩略图.裁切. ...

  5. JAVA上百实例源码以及开源项目

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级.中级.高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情.执着,对IT的憧憬. ...

  6. 优秀java开源项目与解决方案推荐与概论

    http://www.oschina.net/project/lang/19/java http://www.open-open.com/ http://java-source.net/ https: ...

  7. 两个月的Java实习结束,继续努力

    前言 只有光头才能变强 2018年8月30日,今天我辞职了.在6月25号入职,到现在也有两个月时间了. 感受: 第一天是期待的:第一次将项目拉到本地上看的时候,代码很多,有非常多的模块,模块下又有da ...

  8. JAVA上百实例源码网站

    JAVA源码包1JAVA源码包2JAVA源码包3JAVA源码包4 JAVA开源包1 JAVA开源包2 JAVA开源包3 JAVA开源包4 JAVA开源包5 JAVA开源包6 JAVA开源包7 JAVA ...

  9. JAVA图像缩放处理

    http://www.blogjava.net/kinkding/archive/2009/05/23/277552.html ———————————————————————————————————— ...

随机推荐

  1. vue学习过程总结(02)- 网上开源项目vue-element-admin的启动

    1.功能丰富的项目:https://github.com/PanJiaChen/vue-element-admin.git 因为我配置的时候,遇到许多的问题,用了一天半才启动的,所以安着他文档一步一步 ...

  2. 知识点简单总结——minmax容斥

    知识点简单总结--minmax容斥 minmax容斥 好像也有个叫法叫最值反演? 就是这样的一个柿子: \[max(S) = \sum\limits_{ T \subseteq S } min(T) ...

  3. linux下串口测试程序

    通过简单的参数配置,执行文件+串口号+波特率 #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...

  4. VT 入门番外篇——初识 VT

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  5. JavaScript的访问器

    一.访问器属性: 1.Configurable:表示能否通过delete删除属性,从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性.对于直接在对象上定义的属性,这个特性的默认值为tr ...

  6. jQuery--文档处理案例

    需求 如上图,实现左右两边的选择菜单可以左右移动,'>'按钮一次只能移动被选中的一个菜单,'>>'按钮一次移动所有被选择的菜单,'>>>'按钮 将所有菜单进行移动, ...

  7. java的jsr303校验

    因为是菜鸡,所以就还没有具体了解jsr303具体是什么 JSR是Java Specification Requests的缩写,意思是Java 规范提案.是指向JCP(Java Community Pr ...

  8. 写一段代码在遍历 ArrayList 时移除一个元素?

    该问题的关键在于面试者使用的是 ArrayList 的 remove() 还是 Iterator 的 remove()方法.这有一段示例代码,是使用正确的方式来实现在遍历的过程中移 除元素,而不会出现 ...

  9. Mybatis入门程序(二)

    1.实现需求 添加用户 更新用户 删除用户 2.添加用户 (1)映射文件User.xml(Mapper)中,配置添加用户的Statement <!-- 添加用户: parameterType:指 ...

  10. idea中Git的配置和Github上推拉项目

    1.去官网下载Git,并且安装它.安装步骤较为简单,此处就不再赘述. 2.在idea中配置Git信息 Git路径就是你电脑中安装Git的位置,找到git.exe文件(正常情况下,idea都会自动给你匹 ...