基于现有图像数据创建自定义像素格式的 BufferedImage
在最近的一个项目中,需要实现 Mac OS X 环境下的摄像头图像实时捕获并转换为 Java 中的 BufferedImage 对象。首先通过开发一个本地库实现 Mac OS X 的摄像头图像捕获,采用的是 Apple 推荐的新的 AVFoundation 框架,摄像头图像格式设置为 kCVPixelFormatType_32ARGB(设置成其他的测试了无法得到图像,系统不支持),通过 delegate 方式得到 CMSampleBufferRef 类型的 sample buffer 后,需要通过 CMSampleBufferGetImageBuffer 函数将其转换为 CVImageBufferRef 类型的图像缓冲(因为这里捕获的是图像数据,并不是采样数据,所以不能用 CMSampleBufferGetDataBuffer)。然后通过 CVPixelBufferGetBaseAddress 函数得到图像缓冲的首地址,用 CVPixelBufferGetDataSize 函数得到图像缓冲区数据大小,但这里千万要注意,不要以为这时获取的图像缓冲区数据就可以通过Java 的 Raster 和 DataBuffer 等方式来直接填充 Java 中的 BufferedImage(这里假定 BufferedImage 采用 TYPE_INT_ARGB,因为想着对应 kCVPixelFormatType_32ARGB)。因为这么做了会发现图像颜色完全是错乱的,事实上,我们通过计算就可以知道,对应高、宽下的 TYPE_INT_ARGB 格式的 BufferedImage 图像数据大小为 width × height × 4 字节(因为这时一个像素为 int 类型,4 字节大小),但 CVPixelBufferGetDataSize 得到的图像数据大小总比前者要多 4 个字节,可能是保存了其他的一些信息。所以这里直接创建 TYPE_INT_ARGB 格式的 BufferedImage 然后用 Raster 以及 DataBuffer 等方式进行填充是行不通的。
这里就需要采取另外的方式,用 DataBufferByte、ComponentSampleModel、WritableRaster、ColorSpace、ColorModel 来构建 BufferedImage,其实也是使用了 BufferedImage 的另一种不常用的、但效率非常高的构造函数模式。当然,前提是还需要通过 CVPixelBufferGetBytesPerRow 函数得到图像中每个扫描行的字节数,通过 CVPixelBufferGetHeight 函数得到图像的高度,通过 CVPixelBufferGetWidth 函数得到图像的宽度,后面会用得上。具体如以下代码:
DataBufferByte dataBufferByte = new DataBufferByte(new byte[][] {dataBytes}, dataSize); // 这里假定 dataBytes 保存了本地获取的图像数据,dataSize 为图像数据大小(总是比“w * h * 每像素字节数”计算出来要大一点)
ComponentSampleModel componentSampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 4, bytesPerRow, new int[] {1, 2, 3, 0}); // 自定义 BufferedImage 中的图像格式,还是以字节来存储每个像素,具体构造函数的说明见 javadoc api
WritableRaster writableRaster = Raster.createWritableRaster(componentSampleModel, dataBufferByte, new Point(0, 0)); // 创建包含具体图像数据的栅格阵列
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); // 创建 RGB 颜色空间
int[] nBits = {8, 8, 8, 8}; // 对应源图像数据的 ARGB,因为源图像数据采用 32ARGB,等效于 4 个字节,每个字节按顺序分别表示 alpha、red、green、blue
ColorModel colorModel = new ComponentColorModel(colorSpace, nBits, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); // 创建颜色模式
BufferedImage bufferedImage = new BufferedImage(colorModel, writableRaster, false, null); // 构建自定义像素格式的 BufferedImage
这种方式就不会出现问题了,本地库捕获的实时摄像头图像能够正确填充到 Java 的 BufferedImage 中,而且效率非常高。
基于现有图像数据创建自定义像素格式的 BufferedImage的更多相关文章
- NumPy 基于已有数据创建数组
原文:Python Numpy 教程 章节 Numpy 介绍 Numpy 安装 NumPy ndarray NumPy 数据类型 NumPy 数组创建 NumPy 基于已有数据创建数组 NumPy 基 ...
- .Net Core WebApi返回的json数据,自定义日期格式
基本上所有的人都在DateTime类型的字段,被序列化成json的时候,遇到过可恨的Date(1294499956278+0800):但是又苦于不能全局格式化设置,比较难受.以往的方式,要么使用全局的 ...
- ASP.Net Core 返回的json数据,自定义日期格式
//代码位置:Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddMvc() .Ad ...
- CAFFE学习笔记(四)将自己的jpg数据转成lmdb格式
1 引言 1-1 以example_mnist为例,如何加载属于自己的测试集? 首先抛出一个问题:在example_mnist这个例子中,测试集是人家给好了的.那么如果我们想自己试着手写几个数字然后验 ...
- Excel 2007中自定义数字格式前要了解的准则
要在Excel 2007中创建自定义数字格式,首先应了解自定义数字格式的准则,并从选择某一内置数字格式开始.然后,可以更改该格式的任意代码部分,从而创建自己的自定义数字格式. 数字格式最多可包含四个代 ...
- .net下灰度模式图像在创建Graphics时出现:无法从带有索引像素格式的图像创建graphics对象 问题的解决方案。
在.net下,如果你加载了一副8位的灰度图像,然后想向其中绘制一些线条.或者填充一些矩形.椭圆等,都需要通过Grahpics.FromImage创建Grahphics对象,而此时会出现:无法从带有索引 ...
- 无法从带有索引像素格式的图像创建graphics对象(转)
大家在用 .NET 做图片水印功能的时候, 很可能会遇到 “无法从带有索引像素格式的图像创建graphics对象”这个错误,对应的英文错误提示是“A Graphics object cannot be ...
- 无法从带有索引像素格式的图像创建graphics对象
大家在用 .NET 做图片水印功能的时候, 很可能会遇到 “无法从带有索引像素格式的图像创建graphics对象”这个错误,对应的英文错误提示是“A Graphics object cannot be ...
- .Net给图片加水印,并解决“无法从带有索引像素格式的图像创建Graphics对象”问题
using (Image img = Image.FromFile(savePath)) { //如果原图片是索引像素格式之列的,则需要转换 if (img.PixelFormat!=null) { ...
随机推荐
- Latex使用笔记,中文,字号等
中文 编译器选择的xelatex 或者lualatex 我试过的两种方式(都是基于ctex的). 直接使用ctex的基本documentclass \documentclass[UTF8]{ctexa ...
- 【NOIP提高A组模拟2018.8.14】 区间
区间加:差分数组修改 O(n)扫描,负数位置单调不减 #include<iostream> #include<cstring> #include<cstdio> # ...
- GoogleTest 之路2-Googletest 入门(Primer)
Why googletest? 为啥要用GoogleTest呢? googletest 是由测试技术Team 开发的带有google 特殊的需求和限制的测试框架. 不管你在什么平台上写C++代码,go ...
- 【laravel】Laravel 5 TokenMismatchException on PHP 5.6.9
When I realized this was only happening in IE and Chrome, but not Firefox, it led me to the fix. The ...
- 解决 viewer.js 动态更新图片导致无法预览的问题
1.viewer.js 使用 Demo http://fengyuanchen.github.io/viewerjs/ 2.viewer.js 下载地址 https://github.com/feng ...
- Applied Nonparametric Statistics-lec4
Ref: https://onlinecourses.science.psu.edu/stat464/print/book/export/html/5 Two sample test 直接使用R的t- ...
- 通过IAR工程文件查看对应IAR版本号
IAR使用技巧——如何使用合适的版本打开IAR工程 2014年07月05日 23:49:08 xukai871105 阅读数:12895 标签: IAR 更多 个人分类: 嵌入式ARM 0.前言 ...
- 某比赛小记1- 挑选第N大数字
题目:给1000个数字(有重复),从小到大排列后,挑选第N个数字. 数字文件如下:numbers.rar ,挑选第727个数字. java版本: //数组初始化 String str = " ...
- HTTP认证之基本认证——Basic(二)
导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 在HTTP认证 ...
- bzoj3039 joyoi1939 玉蟾宫 悬线法
悬线法 #include <iostream> #include <cstring> #include <cstdio> using namespace std; ...