麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

基于現(xiàn)有圖像數(shù)據(jù)創(chuàng)建自定義像素格式的BufferedImage

2019-11-14 14:53:07
字體:
供稿:網(wǎng)友

在最近的一個(gè)項(xiàng)目中,需要實(shí)現(xiàn) Mac OS X 環(huán)境下的攝像頭圖像實(shí)時(shí)捕獲并轉(zhuǎn)換為 java 中的 BufferedImage 對象。首先通過開發(fā)一個(gè)本地庫實(shí)現(xiàn) Mac OS X 的攝像頭圖像捕獲,采用的是 Apple 推薦的新的 AVFoundation 框架,攝像頭圖像格式設(shè)置為 kCVPixelFormatType_32ARGB(設(shè)置成其他的測試了無法得到圖像,系統(tǒng)不支持),通過 delegate 方式得到 CMSampleBufferRef 類型的 sample buffer 后,需要通過 CMSampleBufferGetImageBuffer 函數(shù)將其轉(zhuǎn)換為 CVImageBufferRef 類型的圖像緩沖(因?yàn)檫@里捕獲的是圖像數(shù)據(jù),并不是采樣數(shù)據(jù),所以不能用 CMSampleBufferGetDataBuffer)。然后通過 CVPixelBufferGetBaseAddress 函數(shù)得到圖像緩沖的首地址,用 CVPixelBufferGetDataSize 函數(shù)得到圖像緩沖區(qū)數(shù)據(jù)大小,但這里千萬要注意,不要以為這時(shí)獲取的圖像緩沖區(qū)數(shù)據(jù)就可以通過Java 的 Raster 和 DataBuffer 等方式來直接填充 Java 中的 BufferedImage(這里假定 BufferedImage 采用 TYPE_INT_ARGB,因?yàn)橄胫鴮?yīng) kCVPixelFormatType_32ARGB)。因?yàn)檫@么做了會發(fā)現(xiàn)圖像顏色完全是錯(cuò)亂的,事實(shí)上,我們通過計(jì)算就可以知道,對應(yīng)高、寬下的 TYPE_INT_ARGB 格式的 BufferedImage 圖像數(shù)據(jù)大小為 width × height × 4 字節(jié)(因?yàn)檫@時(shí)一個(gè)像素為 int 類型,4 字節(jié)大小),但 CVPixelBufferGetDataSize 得到的圖像數(shù)據(jù)大小總比前者要多 4 個(gè)字節(jié),可能是保存了其他的一些信息。所以這里直接創(chuàng)建 TYPE_INT_ARGB 格式的 BufferedImage 然后用 Raster 以及 DataBuffer 等方式進(jìn)行填充是行不通的。

這里就需要采取另外的方式,用 DataBufferByte、ComponentSampleModel、WritableRaster、ColorSpace、ColorModel 來構(gòu)建 BufferedImage,其實(shí)也是使用了 BufferedImage 的另一種不常用的、但效率非常高的構(gòu)造函數(shù)模式。當(dāng)然,前提是還需要通過 CVPixelBufferGetBytesPerRow 函數(shù)得到圖像中每個(gè)掃描行的字節(jié)數(shù),通過 CVPixelBufferGetHeight 函數(shù)得到圖像的高度,通過 CVPixelBufferGetWidth 函數(shù)得到圖像的寬度,后面會用得上。具體如以下代碼:

1 DataBufferByte dataBufferByte = new DataBufferByte(new byte[][] {dataBytes}, dataSize); // 這里假定 dataBytes 保存了本地獲取的圖像數(shù)據(jù),dataSize 為圖像數(shù)據(jù)大小(總是比“w * h * 每像素字節(jié)數(shù)”計(jì)算出來要大一點(diǎn))2 ComponentSampleModel componentSampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 4, bytesPerRow, new int[] {1, 2, 3, 0}); // 自定義 BufferedImage 中的圖像格式,還是以字節(jié)來存儲每個(gè)像素,具體構(gòu)造函數(shù)的說明見 javadoc api3 WritableRaster writableRaster = Raster.createWritableRaster(componentSampleModel, dataBufferByte, new Point(0, 0)); // 創(chuàng)建包含具體圖像數(shù)據(jù)的柵格陣列4 ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); // 創(chuàng)建 RGB 顏色空間5 int[] nBits = {8, 8, 8, 8}; // 對應(yīng)源圖像數(shù)據(jù)的 ARGB,因?yàn)樵磮D像數(shù)據(jù)采用 32ARGB,等效于 4 個(gè)字節(jié),每個(gè)字節(jié)按順序分別表示 alpha、red、green、blue6 ColorModel colorModel = new ComponentColorModel(colorSpace, nBits, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); // 創(chuàng)建顏色模式7 BufferedImage bufferedImage = new BufferedImage(colorModel, writableRaster, false, null); // 構(gòu)建自定義像素格式的 BufferedImage

這種方式就不會出現(xiàn)問題了,本地庫捕獲的實(shí)時(shí)攝像頭圖像能夠正確填充到 Java 的 BufferedImage 中,而且效率非常高。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: www国产成人免费观看视频 | 欧美日韩大片在线观看 | 国产一区二区影视 | 国产亚洲精品影达达兔 | 免费国产视频在线观看 | 极品大长腿啪啪高潮露脸 | 双性帝王调教跪撅打屁股 | 国产日韩在线观看一区 | 国产成人精品免费视频大全办公室 | 一级α片免费看刺激高潮视频 | 精品国产乱码久久久久久丨区2区 | 国产午夜精品一区二区三区嫩草 | 91精品国产91久久久久久 | 久久亚洲网| 一本大道av| 成人国产精品免费 | 暴力肉体进入hdxxxx古装 | 黄色网电影| 麻豆视频在线观看 | 精品免费久久 | 欧美三级短视频 | 国产羞羞网站 | 欧美日韩在线中文字幕 | 日韩视频在线观看免费 | av不卡免费在线 | 国产一区免费 | 久久久久久久久久久久久久av | 日韩剧情片 | 久久精品中文字幕一区 | 中文字幕在线亚洲 | 久久国产精品久久久久久久久久 | 国产瑟瑟视频 | 亚洲精品com | 欧洲色阁中文字幕 | 91avsese| 中文字幕观看 | 国产精品视频海角社区88 | 国产精品一区在线观看 | 91久久夜色精品国产网站 | 精品中文字幕在线播放 | 天天舔天天插 |