99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

HarmonyOS應(yīng)用圖像stride處理方案

HarmonyOS開發(fā)者 ? 來源:HarmonyOS開發(fā)者 ? 2025-06-10 14:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

概述

在計算機圖形學(xué)和圖像處理中,stride通常指的是在內(nèi)存中存儲多維數(shù)組(如圖像或紋理)時,行與行之間的字節(jié)間隔,即每一行的起始地址與下一行的起始地址之間的距離,在本文中stride指的是圖像的一行數(shù)據(jù)在內(nèi)存中實際占用的字節(jié)數(shù),為了內(nèi)存對齊和提高讀取效率的要求,通常大于圖像的寬度。在解析圖像內(nèi)容時,如果未考慮stride,直接通過使用width*height讀取圖像內(nèi)容去解析圖像,會導(dǎo)致相機預(yù)覽異常;當(dāng)預(yù)覽流圖像stride與width不一致時,需要對stride進行無效像素去除處理。

實現(xiàn)原理

當(dāng)圖像存儲在內(nèi)存中時,內(nèi)存緩沖區(qū)可能在每行像素之后包含額外的填充字節(jié)。填充字節(jié)會影響圖像在內(nèi)存中的存儲方式,但不會影響圖像的顯示方式。stride是內(nèi)存中一行像素到內(nèi)存中下一行像素的字節(jié)數(shù);如果存在填充字節(jié),則步幅比圖像的寬度寬。

說明:stride在不同的平臺底層上報的值不同,開發(fā)者需根據(jù)實際業(yè)務(wù)獲取stride后做處理適配。在本文中通過預(yù)覽流幀數(shù)據(jù)的返回值image.Component.rowStride獲取stride。

如下圖:在一個width為3,height為3,stride為4的圖片上(例如定義了一個480*480分辨率的圖像),實際分配內(nèi)存并不是width*height即3*3(此處為定義的預(yù)覽流分辨率的寬高比,即實際分配內(nèi)存不是480*480),而是stride*height即4*3,這樣實現(xiàn)了內(nèi)存對齊,方便硬件處理。

b5894736-428c-11f0-b715-92fbcf53809c.png

圖1:需正確處理stride

如果開發(fā)者根據(jù)width和height數(shù)據(jù)去處理像素數(shù)據(jù),即把0x00-0x09地址的數(shù)據(jù)當(dāng)做像素去處理,就會出現(xiàn)解析了錯誤的像素數(shù)據(jù)的問題,并且使用了無效的像素0x03,0x07,會導(dǎo)致圖片無法正常顯示導(dǎo)致“相機花屏”現(xiàn)象。因此,要根據(jù)stride值處理預(yù)覽數(shù)據(jù)流,去除無效的像素后送顯,才能獲取正確的預(yù)覽流圖像。

場景案例

以一種高頻的用戶使用場景為例,應(yīng)用需要定義一個1080*1080分辨率的預(yù)覽流圖像,此時的stride在相關(guān)平臺的返回值為1088,此時需要對stride進行處理,處理無效像素后解析出正確的像素數(shù)據(jù),避免出現(xiàn)預(yù)覽流花屏。

【反例】未處理stride:當(dāng)開發(fā)者創(chuàng)建PixelMap解析buffer時,直接按照寬去讀取每行數(shù)據(jù),沒有處理stride,此時若解析了無效像素數(shù)據(jù)并傳給Image組件直接送顯,可能會出現(xiàn)預(yù)覽流花屏現(xiàn)象。

以下為部分示例代碼:

1. 應(yīng)用通過image.ImageReceiver注冊imageArrival圖像回調(diào)方法,獲取每幀圖像數(shù)據(jù)實例image.Image,應(yīng)用通過定義一個width為1080*height為1080分辨率的預(yù)覽流直接創(chuàng)建pixelMap,此時獲取到的stride的值為1088,解析buffer時若直接按照寬去讀取每行數(shù)據(jù)(使用了無效像素數(shù)據(jù))并存儲到全局變量stridePixel中,傳給Image送顯,會導(dǎo)致預(yù)覽流花屏。

onImageArrival(receiver: image.ImageReceiver):void{
receiver.on('imageArrival',() =>{
  receiver.readNextImage((err: BusinessError, nextImage: image.Image) =>{
 if(err || nextImage ===undefined) {
   Logger.error(TAG,`requestPermissionsFromUser call Failed! error:${err.code}`);
   return;
  }
 if(nextImage) {
    nextImage.getComponent(image.ComponentType.JPEG,async(_err,component: image.Component) => {
   letwidth =1080;// width為應(yīng)用創(chuàng)建預(yù)覽流分辨率對應(yīng)的寬
   letheight =1080;// height為應(yīng)用創(chuàng)建預(yù)覽流分辨率對應(yīng)的高
   // component.byteBuffer為相機返回的預(yù)覽流數(shù)據(jù),其中包含了stride對齊數(shù)據(jù)
   letpixelMap =awaitimage.createPixelMap(component.byteBuffer, {
     size: {
     height: height,
     width: width
      },
     // 反例:width沒有處理stride值,創(chuàng)建PixelMap解析buffer時直接按照寬去讀取每行數(shù)據(jù),可能使用了無效像素數(shù)據(jù),導(dǎo)致預(yù)覽流花屏。
     srcPixelFormat: image.PixelMapFormat.NV21
    })
   AppStorage.setOrCreate('stridePixel', pixelMap);// 將創(chuàng)建出的PixelMap存儲到全局變量stridePixel中并傳給Image組件送顯。
    nextImage.release();
    })
  }
  });
})
}

2. 在初始相機模塊時,調(diào)用onImageArrival(),將未處理的width和height作為size,創(chuàng)建PixelMap,通過在Image中傳入被@StorageLink修飾的變量stridePixel進行數(shù)據(jù)刷新,圖片送顯。

@Component
exportstructPageThree{
pathStack:NavPathStack=newNavPathStack();
@StateisShowStridePixel:boolean=false;
@StorageLink('stridePixel')@Watch('onStridePixel')stridePixel: image.PixelMap|undefined=undefined;
@StateimageWidth:number=1080;
@StateimageHeight:number=1080;
@StorageLink('previewRotation')previewRotate:number=0;
onStridePixel():void{
 this.isShowStridePixel=true;
}
aboutToAppear():void{
 CameraService.initCamera(0);
}
aboutToDisappear():void{
 CameraService.releaseCamera();
}
// ...
build() {
 NavDestination() {
 // ...
 Column() {
   if(this.isShowStridePixel) {
   Image(this.stridePixel)// 反例:解析了錯誤的像素數(shù)據(jù),并存儲到全局變量stridePixel中,傳給Image送顯,會導(dǎo)致相機預(yù)覽流花屏。
      .width(px2vp(this.imageWidth))
      .height(px2vp(this.imageHeight))
      .margin({top:150})
      .rotate({
     z:0.5,
     angle:this.previewRotate
      })
    }
   // ...
  }
  .justifyContent(FlexAlign.Center)
  .height('90%')
  .width('100%')
  }
  .backgroundColor(Color.White)
  .hideTitleBar(true)
  .onBackPressed(() =>{
 this.pathStack.pop();
 returntrue;
  })
  .onReady((context: NavDestinationContext) =>{
 this.pathStack= context.pathStack;
  })
}
}

【正例一】開發(fā)者使用width,height,stride三個值,處理相機預(yù)覽流數(shù)據(jù),處理stride方法一如下。分兩種情況:

1. 當(dāng)stride和width相等時,按寬讀取buffer不影響結(jié)果。

2. 當(dāng)stride和width不等時,將相機返回的預(yù)覽流數(shù)據(jù)即component.byteBuffer的數(shù)據(jù)去除stride,拷貝得到新的dstArr數(shù)據(jù)進行數(shù)據(jù)處理,將處理后的dstArr數(shù)組buffer,通過width和height直接創(chuàng)建pixelMap, 并存儲到全局變量stridePixel中,傳給Image送顯。

onImageArrival(receiver: image.ImageReceiver):void{
receiver.on('imageArrival',() =>{
  receiver.readNextImage((err: BusinessError, nextImage: image.Image) =>{
 // ...
 if(nextImage) {
    nextImage.getComponent(image.ComponentType.JPEG,
   async(err,component: image.Component) => {
     letwidth =1080;// width為應(yīng)用創(chuàng)建預(yù)覽流分辨率對應(yīng)的寬
     letheight =1080;// height為應(yīng)用創(chuàng)建預(yù)覽流分辨率對應(yīng)的高
     letstride = component.rowStride;// 通過component.rowStride獲取stride
     // 正例:情況1. 當(dāng)圖片的width等于相機預(yù)覽流返回的行跨距stride,此時無需處理stride,通過width和height直接創(chuàng)建pixelMap,
     // 并存儲到全局變量stridePixel中,傳給Image送顯。
     if(stride === width) {
     letpixelMap =awaitimage.createPixelMap(component.byteBuffer, {
       size: {height: height,width: width },
       srcPixelFormat: image.PixelMapFormat.NV21,
      })
     AppStorage.setOrCreate('stridePixel', pixelMap);
      }else{
     // 正例:情況2. 當(dāng)圖片的width不等于相機預(yù)覽流返回的行跨距stride,
     // 此時將相機返回的預(yù)覽流數(shù)據(jù)component.byteBuffer去除掉stride,拷貝得到新的dstArr數(shù)據(jù),數(shù)據(jù)處理后傳給其他不支持stride的接口處理。
     constdstBufferSize = width * height *1.5;// 創(chuàng)建一個width * height * 1.5的dstBufferSize空間,此處為NV21數(shù)據(jù)格式。
     constdstArr =newUint8Array(dstBufferSize);// 存放去掉stride后的buffer。
     // 讀取每行數(shù)據(jù),相機支持的profile寬高均為偶數(shù),不涉及取整問題。
     for(letj =0; j < height *?1.5; j++) {?// 循環(huán)dstArr的每一行數(shù)據(jù)。
? ? ? ? ? ? ? ??// 拷貝component.byteBuffer的每行數(shù)據(jù)前width個字節(jié)到dstArr中(去除無效像素,剛好每行得到一個width*height的八字節(jié)數(shù)組空間)。
? ? ? ? ? ? ? ??const?srcBuf =?new?Uint8Array(component.byteBuffer, j * stride,
? ? ? ? ? ? ? ? width);?// 將component.byteBuffer返回的buffer,每行遍歷,從首位開始,每行截取出width字節(jié)。
? ? ? ? ? ? ? ? dstArr.set(srcBuf, j * width);?// 將width*height大小的數(shù)據(jù)存儲到dstArr中。
? ? ? ? ? ? }
? ? ? ? ? ??let?pixelMap =?await?image.createPixelMap(dstArr.buffer, {
? ? ? ? ? ? ? ??// 將處理后的dstArr數(shù)組buffer,通過width和height直接創(chuàng)建pixelMap,并存儲到全局變量stridePixel中,傳給Image送顯。
? ? ? ? ? ? ? ??size: {?height: height,?width: width },
? ? ? ? ? ? ? ??srcPixelFormat: image.PixelMapFormat.NV21,
? ? ? ? ? ? })
? ? ? ? ? ??AppStorage.setOrCreate('stridePixel', pixelMap);
? ? ? ? ? ? }
? ? ? ? ? ? nextImage.release();
? ? ? ? })
? ? }
? ? });
})
}

【正例二】開發(fā)者使用width,height,stride三個值,處理相機預(yù)覽流數(shù)據(jù),處理stride方法二如下。分兩種情況:

1. 當(dāng)stride和width相等時,與正例一情況一致,此處不再贅述。

2. 當(dāng)stride和width不等時,如果應(yīng)用想使用byteBuffer預(yù)覽流數(shù)據(jù)創(chuàng)建pixelMap直接顯示,可以根據(jù)stride*height字節(jié)的大小先創(chuàng)建pixelMap,然后調(diào)用PixelMap的cropSync方法裁剪掉多余的像素,從而正確處理stride,解決預(yù)覽流花屏問題。

onImageArrival(receiver: image.ImageReceiver):void{
receiver.on('imageArrival',() =>{
  receiver.readNextImage((err: BusinessError, nextImage: image.Image) =>{
 // ...
 if(nextImage) {
    nextImage.getComponent(image.ComponentType.JPEG,async(_err,component: image.Component) => {
   letwidth =1080;// width為應(yīng)用創(chuàng)建預(yù)覽流分辨率對應(yīng)的寬
   letheight =1080;// height為應(yīng)用創(chuàng)建預(yù)覽流分辨率對應(yīng)的高
   letstride = component.rowStride;// 通過component.rowStride獲取stride
   Logger.info(TAG,`receiver getComponent width:${width}height:${height}stride:${stride}`);
   // stride和width相等,按寬讀取buffer不影響結(jié)果
   if(stride === width) {
     letpixelMap =awaitimage.createPixelMap(component.byteBuffer, {
     size: {height: height,width: width },
     srcPixelFormat: image.PixelMapFormat.NV21,
      })
     AppStorage.setOrCreate('stridePixel', pixelMap);
    }else{
     letpixelMap =awaitimage.createPixelMap(component.byteBuffer, {
     // 正例:1、創(chuàng)建PixelMap時width傳stride,
     size: {height: height,width: stride },
     srcPixelFormat:8,
      })
     // 2、然后調(diào)用PixelMap的cropSync方法裁剪掉多余的像素。
      pixelMap.cropSync({
     size: {width: width,height: height },
     x:0,
     y:0
      })// 根據(jù)輸入的尺寸裁剪圖片,從(0,0)開始,裁剪width*height字節(jié)的區(qū)域。
     letpixelBefore:PixelMap|undefined=AppStorage.get('stridePixel');
     awaitpixelBefore?.release();
     AppStorage.setOrCreate('stridePixel', pixelMap);
    }
    nextImage.release();
    })
  }
  });
})
}

常見問題

如何獲取相機預(yù)覽流幀數(shù)據(jù)

通過ImageReceiver中imageArrival事件監(jiān)聽獲取底層返回的圖像數(shù)據(jù)。

如何獲取預(yù)覽流圖像的stride的值

可以通過預(yù)覽流幀數(shù)據(jù)的返回值image.Component.rowStride獲取stride。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 計算機
    +關(guān)注

    關(guān)注

    19

    文章

    7667

    瀏覽量

    90864
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3125

    瀏覽量

    75295
  • 圖像
    +關(guān)注

    關(guān)注

    2

    文章

    1094

    瀏覽量

    41301
  • HarmonyOS
    +關(guān)注

    關(guān)注

    80

    文章

    2126

    瀏覽量

    33154

原文標(biāo)題:HarmonyOS應(yīng)用圖像stride處理方案

文章出處:【微信號:HarmonyOS_Dev,微信公眾號:HarmonyOS開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    模糊圖像處理解決方案

    造成圖像模糊的原因有很多,且不同原因?qū)е碌哪:?b class='flag-5'>圖像需要不同的方法來進行處理。##圖像復(fù)原
    發(fā)表于 06-11 10:24 ?1.3w次閱讀

    《DNK210使用指南 -CanMV版 V1.0》第三十五章 image圖像特征檢測實驗

    ))image模塊為Image對象提供了find_circles()方法,用于檢測圖像中的圓形特征,find_circles()方法如下所示:image.find_circles(roi, x_stride
    發(fā)表于 11-06 09:30

    ADAS方案設(shè)計成功關(guān)鍵:圖像處理技術(shù)

    的汽車電子半導(dǎo)體供應(yīng)商Renesas(瑞薩)在國內(nèi)最大的代理商之一,世強已聯(lián)合第三方合作伙伴推出了基于瑞薩最新圖像處理器SH7766的高級汽車環(huán)視輔助駕駛系統(tǒng)方案,受到很多客戶關(guān)注?!翱蛻魧Υ?b class='flag-5'>
    發(fā)表于 09-01 17:09

    DSP圖像處理系統(tǒng)中信號完整性問題及解決方案

    什么是DSP圖像處理系統(tǒng)?DSP圖像處理系統(tǒng)中信號完整性的問題是什么?有哪些解決方案
    發(fā)表于 06-01 06:40

    【資料】華為HarmonyOS 圖像開發(fā)指南

    華為HarmonyOS 圖像開發(fā)指南回復(fù)帖子查看資料下載鏈接:[hide][/hide]
    發(fā)表于 08-12 12:03

    如何使用Stride模式?

    Stride模式是一種特殊的PDMA模式,它可以將某個內(nèi)存的數(shù)據(jù)移動到另一個內(nèi)存,間隔和數(shù)量固定。 例如,有一個連續(xù)的內(nèi)存區(qū)塊。內(nèi)容數(shù)據(jù)是圖片顏色信息,順序固定為紅色、綠色、藍色。用斯特里德模式
    發(fā)表于 08-28 06:36

    Altera的視頻和圖像處理解決方案

    Altera的視頻和圖像處理解決方案圖1. 解決方案領(lǐng)域 Altera及其合作伙伴的多種開發(fā)套件、IP和參考設(shè)計為視頻和圖像處理
    發(fā)表于 06-08 07:51 ?52次下載

    圖像處理技術(shù)是什么_圖像處理技術(shù)現(xiàn)狀和發(fā)展前景

    數(shù)字圖像處理技術(shù)正在向處理算法更優(yōu)化、處理速度更快、處理后的圖像清晰度更高的方向發(fā)展,實現(xiàn)
    發(fā)表于 01-12 17:47 ?5.6w次閱讀

    基于matlab GUI的彩色圖像處理技術(shù)設(shè)計方案資料下載

    基于matlab GUI的彩色圖像處理技術(shù)設(shè)計方案資料
    發(fā)表于 05-11 10:32 ?29次下載

    OmniTek 超清HDTV圖像處理方案演示

    OmniTek 總裁 Mike Hodson 將向您演示他們的超清 HDTV 圖像處理解決方案
    的頭像 發(fā)表于 06-01 14:53 ?5532次閱讀
    OmniTek 超清HDTV<b class='flag-5'>圖像</b><b class='flag-5'>處理</b><b class='flag-5'>方案</b>演示

    基于FPGA的HEIF圖像處理加速方案

    近日,元腦生態(tài)伙伴深維科技與浪潮聯(lián)合發(fā)布業(yè)內(nèi)首個基于FPGA的HEIF圖像處理加速方案。
    的頭像 發(fā)表于 10-23 11:16 ?2792次閱讀
    基于FPGA的HEIF<b class='flag-5'>圖像</b><b class='flag-5'>處理</b>加速<b class='flag-5'>方案</b>

    HarmonyOS的組件化設(shè)計方案

    能力、適配多種終端形態(tài)”,HarmonyOS采用了“組件化”的設(shè)計方案,實現(xiàn)根據(jù)設(shè)備的資源能力和業(yè)務(wù)特征靈活裁剪,滿足不同形態(tài)終端設(shè)備對操作系統(tǒng)的要求。 一、為什么采用“組件化”設(shè)計方案? 分層架構(gòu)是最為流行、應(yīng)用最為廣泛的軟件
    的頭像 發(fā)表于 10-13 09:59 ?2782次閱讀

    HarmonyOS測試技術(shù)與實戰(zhàn)-分布式應(yīng)用測試解決方案

    HDC 2021華為開發(fā)者大會HarmonyOS測試技術(shù)與實戰(zhàn)-HarmonyOS分布式應(yīng)用測試解決方案
    的頭像 發(fā)表于 10-23 14:48 ?1806次閱讀
    <b class='flag-5'>HarmonyOS</b>測試技術(shù)與實戰(zhàn)-分布式應(yīng)用測試解決<b class='flag-5'>方案</b>

    如何利用HLS功能創(chuàng)建圖像處理解決方案

    方案利用 HLS 功能創(chuàng)建圖像處理解決方案,在可編程邏輯中實現(xiàn)邊緣檢測 (Sobel)。
    的頭像 發(fā)表于 05-13 17:47 ?4153次閱讀
    如何利用HLS功能創(chuàng)建<b class='flag-5'>圖像</b><b class='flag-5'>處理解決方案</b>

    機器視覺之圖像增強和圖像處理

    對原始獲取圖像進行一系列的運算處理,稱為圖像處理。圖像處理是機器視覺技術(shù)的方法基礎(chǔ),包括
    發(fā)表于 10-23 10:43 ?935次閱讀
    機器視覺之<b class='flag-5'>圖像</b>增強和<b class='flag-5'>圖像</b><b class='flag-5'>處理</b>