javacpp-FFmpeg系列之3: 像素图像数据转换(BGR与BufferdImage互转,RGB与BufferdImage互转,BufferdImage转Base64编码)
javacpp-ffmpeg系列:
javacpp-FFmpeg系列之1:视频拉流解码成YUVJ420P,并保存为jpg图片
javacpp-FFmpeg系列之2:通用拉流解码器,支持视频拉流解码并转换为YUV、BGR24或RGB24等图像像素数据
javacpp-FFmpeg系列之3: 图像数据转换(BGR与BufferdImage互转,RGB与BufferdImage互转)
补充:
javacpp-FFmpeg系列补充:FFmpeg解决avformat_find_stream_info检索时间过长问题
前言
ffmpeg获取的数据一般为yuv,argb,rgb,bgr,abgr等图像像素数据,我们可能需要转换为java的图像,来方便我们显示他们,当然不需要转换也可以达到我们的目的。
在线演示demo:https://blog.csdn.net/eguid_1/article/details/82842904
项目维护地址:https://github.com/eguid/easyCV
一、那么先来个RGB像素使用的小demo压压惊
(密集恐惧症预警)
通过这个RGB像素的小demo,更容易理解RGB像素格式
public static int getRGB(int[] rgbarr) {//RGB24数组转整型RGB24
int rgb = ((int) rgbarr[0]) & 0xff | (((int) rgbarr[1]) & 0xff) << 8 | (((int) rgbarr[2]) & 0xff) << 16
| 0xff000000;
return rgb;
}
private static int createRandomRgb() {//随机生成RGB24
int[] rgbarr = new int[3];
rgbarr[0] = (int) (Math.random() * 255);
rgbarr[1] = (int) (Math.random() * 255);
rgbarr[2] = (int) (Math.random() * 255);
return getRGB(rgbarr);
}//eguid原创文章,转载请注明出处和作者名(blog.csdn.net/eguid_1)
public static void main(String[] args){
int width = 800, height = 600;//使用整型RGB24
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = createRandomRgb();
image.setRGB(i, j, rgb);
}
}
JLabel label = new JLabel();
label.setSize(width, height);
label.setIcon(new ImageIcon(image));JFrame frame = new JFrame();
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.setVisible(true);
Timer timer=new Timer("定时刷新", true);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb =createRandomRgb();
image.setRGB(i, j, rgb);
}
}
label.repaint();
}
}, 100, 1000/25);
}
运行结果:
二、像素图像数据转换为java图像
上一章我们已经通过ffmpeg获取到了AVFrame,要是能预览这帧视频图像那岂不是更好?
要完成转换为java的图像数据这个转换我们分为两步转换流程。
1、像素图像转换为ByteBuffer
不管是yuv,还是rgb或是bgr,都可以使用该函数转换为ByteBuffer,不同的是ByteBuffer转换为BufferedImage的异同。
//eguid原创文章,转载请注明出处和作者名(https://blog.csdn.net/eguid_1)
public ByteBuffer saveFrame(AVFrame pFrame, int width, int height){
BytePointer data = pFrame.data(0);
int size = width * height * 3;
ByteBuffer buf = data.position(0).limit(size).asBuffer();
return buf;
}
2、ByteBuffer转换为BufferImage
由于不同像素数据转换方法都不相同,以RGB和BGR为例:
(1)BGR24转BufferedImage
/**
* 24位BGR转BufferedImage
* @param src -源数据
* @param width -宽度
* @param height-高度
* @return
*/
public static BufferedImage BGR2BufferedImage(ByteBuffer src,int width,int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
Raster ra = image.getRaster();
DataBuffer out = ra.getDataBuffer();
DataBufferByte db=(DataBufferByte)out;
ByteBuffer.wrap(db.getData()).put(src);
return image;
}
/**
* 24位整型BGR转BufferedImage
* @param src -源数据
* @param width -宽度
* @param height-高度
* @return
*/
public static BufferedImage BGR2BufferedImage(IntBuffer src,int width,int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Raster ra = image.getRaster();
DataBuffer out = ra.getDataBuffer();
DataBufferInt db=(DataBufferInt)out;
IntBuffer.wrap(db.getData()).put(src);
return image;
}
(2)RGB24转BufferedImage
/**
* 24位整型RGB转BufferedImage
* @param src -源数据
* @param width -宽度
* @param height-高度
* @return
*/
public static BufferedImage RGB2BufferedImage(IntBuffer src,int width,int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Raster ra = image.getRaster();
DataBuffer out = ra.getDataBuffer();
DataBufferInt db=(DataBufferInt)out;
IntBuffer.wrap(db.getData()).put(src);
return image;
}
三、一个方便预览BufferImage的小函数
/**
* 使用窗口显示BufferedImage图片
* @param image -BufferedImage
*/
public static void viewImage(BufferedImage image) {
int width=image.getWidth(),height=image.getHeight();
JLabel label = new JLabel();
label.setSize(width, height);
label.setIcon(new ImageIcon(image));JFrame frame = new JFrame();
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.setVisible(true);
}
四、补充
1、BufferImage转Base64编码,方便网页显示
/**
* bufferedImage转base64
* @param format -格式(jpg,png,bmp,gif,jpeg等等)
* @return
* @throws IOException
*/
public static String bufferedImage2Base64(BufferedImage image, String format) throws IOException {
Encoder encoder = Base64.getEncoder();
ByteArrayOutputStream baos = new ByteArrayOutputStream();// 字节流
ImageIO.write(image, format, baos);// 写出到字节流
byte[] bytes=baos.toByteArray();
// 编码成base64
String jpg_base64 = encoder.encodeToString(bytes);
return jpg_base64;
}
2、保存成图片文件
//eguid原创文章,转载请注明出处和作者名(blog.csdn.net/eguid_1)
public static void saveImage(BufferedImage image,String format,String file) throws IOException {
ImageIO.write(image, format, new File(file));
}
javacpp-FFmpeg系列之3: 像素图像数据转换(BGR与BufferdImage互转,RGB与BufferdImage互转,BufferdImage转Base64编码)的更多相关文章
- Caffe框架,图像数据转换成LMDB数据格式
小码农最近在研究深度学习,对所学知识做点记录,以供以后翻阅.在Caffe框架中,数据的格式都是LMDB的,如何将图像数据转换成这个格式呢? 首先,将图像数据和标签生成txt文档,执行一下代码: fin ...
- ffmpeg 系列博客
https://www.ffmpeg.org/download.html#build-macffmpeg 系列博文https://me.csdn.net/blog/leixiaohua1020http ...
- BASE64编码和解码(VC源代码) 并 内存加载 CImage 图像
BASE64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本.完整的BASE64定义可见 RFC1421和 RFC2045.编码后的数据比原始数据略长,为原来的4/3.在电子 ...
- OpenCV中图像的BGR格式及Img对象的属性说明
1. 图像的BGR格式说明 OpenCV中图像读入的数据格式是numpy的ndarray数据格式.是BGR格式,取值范围是[0,255]. 如下图所示,分为三个维度: 第一维度:Height 高度,对 ...
- rust实战系列-base64编码
前言 某些只能使用ASCII字符的场景,往往需要传输非ASCII字符的数据,这时就需要一种编码可以将数据转换成ASCII字符,而base64编码就是其中一种. 编码原理很简单,将原始数据以3字节(24 ...
- caffe学习系列(1):图像数据转换成db(leveldb/lmdb)文件
参考:http://www.cnblogs.com/denny402/p/5082341.html 上述博文用caffe自带的两张图片为例,将图片转为db格式.博主对命令参数进行了详细的解释,很赞. ...
- Caffe学习系列(11):图像数据转换成db(leveldb/lmdb)文件
在深度学习的实际应用中,我们经常用到的原始数据是图片文件,如jpg,jpeg,png,tif等格式的,而且有可能图片的大小还不一致.而在caffe中经常使用的数据类型是lmdb或leveldb,因此就 ...
- Java版流媒体编解码和图像处理(JavaCPP+FFmpeg)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenCV从入门到放弃系列之——如何扫描图像、利用查找表和计时
目的 如何遍历图像中的每一个像素? OpenCV的矩阵值是如何存储的? 如何测试我们所实现算法的性能? 查找表是什么?为什么要用它? 测试用例 颜色空间缩减.具体做法就是:将现有颜色空间值除以某个输入 ...
随机推荐
- POJ 2155 Matrix(二维树状数组,绝对具体)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20599 Accepted: 7673 Descripti ...
- jxl切割excel文件
近期在实施一个项目.当中一项工作是处理历史数据. 客户提供过来的数据是excel表格,超过20万条记录,因为目标系统导入限制,每次仅仅能导入大小不超过8M的文件.所以须要对这些数据进行切割处理.在手工 ...
- HDFS中数据节点数据块存储示例
数据块在数据节点上是按照如下方式存储的. 首先是一个存储的根目录/Hadoop/data/dfs/dn,如下图所示: 接着进入current目录,如下图所示: 再进入后续的BP-433072574-1 ...
- 资源重复 uac.res resource kept(转)
一般按照网上流传的方法制作UAC.RES放到DELPHI程序里面来就可以出现盾牌.但是某些DELPHI的项目在添加了UAC.RES后编译会报错,例如: [DCC Error] E2161 Warnin ...
- mapreduce代码实现入门
mapreduce代码主要包括三个类,map类.reduce类以及测试类! 以wordcount为例, map类为: static class WordMapper extends Mapper< ...
- MyBatis缓存介绍
一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 相同提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存.其存储作用域为 Se ...
- Python 深入剖析SocketServer模块(一)(V2.7.11)
一.简介(翻译) 通用socket server 类 该模块尽力从各种不同的方面定义server: 对于socket-based servers: -- address family: ...
- Unix环境高级编程—进程控制(三)
一.解释器文件 解释器文件属于文本文件,起始行形式为: #! pathname[optional-argument] 我们创建一个只有一行的文件如下: #!/home/webber/test/echo ...
- 【BZOJ4240】有趣的家庭菜园 树状数组+贪心
[BZOJ4240]有趣的家庭菜园 Description 对家庭菜园有兴趣的JOI君每年在自家的田地中种植一种叫做IOI草的植物.JOI君的田地沿东西方向被划分为N个区域,由西到东标号为1~N.IO ...
- Linq Group By 多个字段
var counts = dal.QueryStatisticsCount(condition); var result = from p in counts group p by new { Auc ...