最近在研究使用opencv对普通图片进行扣章的功能,在python上实现了,然后想使用在java上,java在选择jar包时选择了javacv(当然还有更原生的opencv,但由于考虑到后面可能会用到ffmpeg所以还是使用javacv) 到javacv的官网(http://bytedeco.org)上看了下,果然很强大,很多其它的包也有比如:numpy,tensorflow等python中使用到的库。 我是在javacv的sample中找到的相关方法。
/**
* BufferImage转byte[]
* @param original
* @return
*/
public static byte[] bufImg2Bytes(BufferedImage original){
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
try {
ImageIO.write(original, "png", bStream);
} catch (IOException e) {
throw new RuntimeException("bugImg读取失败:"+e.getMessage(),e);
}
return bStream.toByteArray();
}
/**
* byte[]转BufferImage
* @param imgBytes
* @return
*/
public static BufferedImage bytes2bufImg(byte[] imgBytes){
BufferedImage tagImg = null;
try {
tagImg = ImageIO.read(new ByteArrayInputStream(imgBytes));
return tagImg;
} catch (IOException e) {
throw new RuntimeException("bugImg写入失败:"+e.getMessage(),e);
}
}
/**
* BufferedImage 转 mat
* 参考https://github.com/bytedeco/javacv-examples/blob/master/OpenCV_Cookbook/src/main/scala/opencv_cookbook/OpenCVUtils.scala
* @param original
* @return
*/
public static Mat bufImg2Mat (BufferedImage original) {
OpenCVFrameConverter.ToMat openCVConverter = new OpenCVFrameConverter.ToMat();
Java2DFrameConverter java2DConverter = new Java2DFrameConverter();
Mat mat= openCVConverter.convert(java2DConverter.convert(original));
return mat;
}
/**
* mat转BufferedImage
* 参考https://github.com/bytedeco/javacv-examples/blob/master/OpenCV_Cookbook/src/main/scala/opencv_cookbook/OpenCVUtils.scala
* @param matrix
* @return
*/
public static BufferedImage mat2BufImg (Mat matrix) {
Mat tempMat=new Mat();
cvtColor(matrix,tempMat,COLOR_BGRA2RGBA);//先要转bgra->rgba
OpenCVFrameConverter.ToMat openCVConverter = new OpenCVFrameConverter.ToMat();
Java2DFrameConverter java2DConverter = new Java2DFrameConverter();
return java2DConverter.convert(openCVConverter.convert(tempMat));
}
需要说明的opencv中的默认读取的颜色是bgr不是rgb,所以在mat转BufferImage时需要先cvtColor转换一下。
还有更简单的:Java2DFrameUtils 这个类,封装好了。
在使用中发现问题如果BufferedImage为4通道时转Mat会有问题要单独处理,Mat转BufferedImage颜色为蓝色时会有问题建议imwrite后直接用java读
BufferedImage为4通道时是ARGB