精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

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

HarmonyOS開發(fā)案例:【圖片編輯】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-22 16:42 ? 次閱讀

介紹

基于canvas組件、圖片編解碼,介紹了圖片編輯實現(xiàn)過程。主要包含以下功能:

  1. 圖片的解碼和繪制。
  2. 使用PixelMap進行圖片編輯,如裁剪、旋轉(zhuǎn)、亮度調(diào)節(jié)、透明度調(diào)節(jié)、飽和度調(diào)節(jié)等操作。

相關概念

  • [canvas組件]:提供畫布組件。用于自定義繪制圖形。
  • [圖片處理]:提供圖片處理效果,包括通過屬性創(chuàng)建PixelMap、讀取圖像像素數(shù)據(jù)、讀取區(qū)域內(nèi)的圖片數(shù)據(jù)等。

相關權限

本篇Codelab使用了媒體文件存儲能力,需要在配置文件config.json里添加媒體文件讀寫權限:

  • ohos.permission.MEDIA_LOCATION
  • ohos.permission.READ_MEDIA
  • ohos.permission.WRITE_MEDIA

環(huán)境搭建

鴻蒙開發(fā)指導文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]

搜狗高速瀏覽器截圖20240326151344.png

軟件要求

  • [DevEco Studio]版本:DevEco Studio 3.1 Release及以上版本。
  • OpenHarmony SDK版本:API version 9及以上版本。

硬件要求

  • 開發(fā)板類型:[潤和RK3568開發(fā)板]。
  • OpenHarmony系統(tǒng):3.2 Release及以上版本。

環(huán)境搭建

完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進行:

  1. [獲取OpenHarmony系統(tǒng)版本]:標準系統(tǒng)解決方案(二進制)。以3.2 Release版本為例:
  2. 搭建燒錄環(huán)境。
    1. [完成DevEco Device Tool的安裝]
    2. [完成RK3568開發(fā)板的燒錄]
  3. 搭建開發(fā)環(huán)境。
    1. 開始前請參考[工具準備],完成DevEco Studio的安裝和開發(fā)環(huán)境配置。
    2. 開發(fā)環(huán)境配置完成后,請參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”)。
    3. 工程創(chuàng)建完成后,選擇使用[真機進行調(diào)測]。

代碼結(jié)構解讀

本篇Codelab只對核心代碼進行講解,對于完整代碼,我們會在gitee中提供。

├──entry/src/main/js	              // 代碼區(qū)
│  └──MainAbility
│     ├──common
│     │  ├──bean
│     │  │  └──messageItem.js         // 多線程封裝消息
│     │  ├──constant
│     │  │  └──commonConstants.js     // 常量
│     │  ├──images                    // 圖片資源
│     │  └──utils
│     │     ├──adjustUtil.js          // 飽和度、亮度調(diào)節(jié)工具
│     │     ├──imageUtil.js           // 圖片獲取、打包工具
│     │     ├──logger.js              // 日志工具             
│     │     ├──opacityUtil.js         // 透明度調(diào)節(jié)工具
│     │     └──rotateUtil.js          // 旋轉(zhuǎn)工具
│     ├──i18n		                  // 國際化中英文
│     │  ├──en-US.json			
│     │  └──zh-CN.json		
│     ├──model
│     │  └──cropModel.js              // 裁剪數(shù)據(jù)處理
│     ├──pages
│     │  └──index
│     │     ├──index.css              // 首頁樣式文件	
│     │     ├──index.hml              // 首頁布局文件
│     │     └──index.js               // 首頁業(yè)務處理文件
│     ├──workers
│     │  ├──adjustBrightnessWork.js   // 亮度異步調(diào)節(jié)
│     │  └──adjustSaturationWork.js   // 飽和度異步調(diào)節(jié)
│     └──app.js                       // 程序入口
└──entry/src/main/resources           // 應用資源目錄

圖片解碼

本章節(jié)將介紹如何將圖片解碼,并顯示在canvas組件上。需要完成以下功能:

  1. 獲取圖片的PixelMap對象。
  2. 在canvas組件上繪制第一步獲取的PixelMap對象。

在index.js文件的onInit生命周期中初始化canvas畫布,具體有以下步驟:

  1. 調(diào)用imageUtil工具類的getImageFd方法,根據(jù)資源文件獲取圖片fd。
  2. 調(diào)用imageUtil工具類的getImagePixelMap方法,將獲取的fd創(chuàng)建成圖片實例,通過實例獲取其PixelMap。
  3. 通過canvas id獲取CanvasRenderingContext2D對象。
  4. 將獲取的PixelMap繪制到canvas組件上。
// index.js
export default {
  onInit() {
    ...
    this.initCanvas().then(() = > {
      this.postState = false;
    });
  },
  async initCanvas() {
    ...
    // 獲取圖片fd
    this.imageFd = await getImageFd(CommonConstants.IMAGE_NAME);
    // 獲取圖片pixelMap
    this.imagePixelMapAdjust = await getImagePixelMap(this.imageFd);
    ...
    // 獲取canvas對象
    const canvasOne = this.$element('canvasOne');
    this.canvasContext = canvasOne.getContext('2d');
    ...
    // 在canvas組件上繪圖
    this.drawToCanvas(this.imagePixelMapAdjust, this.drawImageLeft, this.drawImageTop,
      this.drawWidth, this.drawHeight);
  }
}

// imageUtil.js
export async function getImageFd(imageName) {
  let mResourceManager = await resourceManager.getResourceManager();
  let rawImageDescriptor = await mResourceManager.getRawFd(imageName);
  let fd = rawImageDescriptor?.fd;
  return fd;
}
export async function getImagePixelMap(fd) {
  let imageSource = image.createImageSource(fd);
  if (!imageSource) {
    return;
  }
  let pixelMap = await imageSource.createPixelMap({
    editable: true,
    desiredPixelFormat: CommonConstants.PIXEL_FORMAT
  });
  return pixelMap;
}

圖片裁剪

本篇Codelab提供四種裁剪比例,全圖裁剪、1:1裁剪、16:9裁剪、4:3裁剪。需要完成以下步驟實現(xiàn)裁剪功能:

  1. 根據(jù)裁剪比例,獲取canvas畫布上需要繪制的裁剪框?qū)捀摺?/li>
  2. 根據(jù)裁剪比例,獲取原圖需要裁剪的寬高。
  3. 根據(jù)第二步獲取的原圖需要裁剪的寬高,對圖片進行裁剪。
  4. 根據(jù)裁剪后原圖寬高,適配屏幕大小,重新繪制。

// index.js
export default {
  // 任意點擊四種裁剪比例
  cropClick(clickIndex) {
    this.cropClickIndex = clickIndex;
    switch (clickIndex) {
      // 全圖裁剪
      case CommonConstants.CropType.ORIGINAL:
        cropOriginal(this);
        break;
      // 1:1裁剪
      case CommonConstants.CropType.ONE_TO_ONE:
        cropSquareImage(this);
        break;
      // 16:9裁剪
      case CommonConstants.CropType.SIXTEEN_TO_NINE:
        cropRectangleImage(this);
        break;
      // 4:3裁剪
      case CommonConstants.CropType.FOUR_TO_THREE:
        cropBannerImage(this);
        break;
      default:
        break;
    }
    drawScreenSelection(this, this.canvasCropContext);
  }
}

以1:1裁剪為例,調(diào)用cropSquareImage方法,獲取原圖需要裁剪的寬高以及裁剪框的寬高。點擊切換編輯類型或保存,調(diào)用cropDrawImage方法裁剪圖片,最后適配屏幕重新繪制。

// cropModel.js
export function cropSquareImage(context) {
  ...
  let length = Math.min(context.originalImage.width, context.originalImage.height);
  // 原圖需要裁剪的寬高
  context.cropWidth = length;
  context.cropHeight = length;
  let drawLength = Math.min(context.drawWidth, context.drawHeight);
  // 裁剪框?qū)捀?/span>
  context.cropDrawWidth = drawLength;
  context.cropDrawHeight = drawLength;
}
export async function cropDrawImage(context) {
  ...
  let imagePixel = context.imagePixelMapAdjust;
  let diffX = (context.originalImage.width - context.cropWidth) / CommonConstants.HALF;
  let diffY = (context.originalImage.height - context.cropHeight) / CommonConstants.HALF;
  context.cropLeft = Math.floor(diffX * accuracy) / accuracy;
  context.cropTop = Math.floor(diffY * accuracy) / accuracy;
  // 裁剪圖片
  await imagePixel.crop({ x: context.cropLeft, y: context.cropTop,
    size: {
      height: context.cropHeight,
      width: context.cropWidth
    }
  });
  // 裁剪后原圖寬高
  context.originalImage.width = context.cropWidth;
  context.originalImage.height = context.cropHeight;
  context.imagePixelMapAdjust = imagePixel;
}

// index.js
// 選擇裁剪框后,裁剪并適應屏幕顯示
async crop() {
  await cropDrawImage(this);
  // 適配屏幕
  this.adjustSize();
  this.canvasCropContext.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
  // 重新繪制
  this.drawToCanvas(this.imagePixelMapAdjust, this.drawImageLeft, this.drawImageTop, this.drawWidth,
    this.drawHeight);
  cropOriginal(this);
}

圖片旋轉(zhuǎn)

本篇Codelab提供逆時針旋轉(zhuǎn)、順時針旋轉(zhuǎn)兩種方式,每次旋轉(zhuǎn)角度為90度。在index.html文件中,使用兩個image組件實現(xiàn)逆時針旋轉(zhuǎn)、順時針旋轉(zhuǎn)按鈕。點擊對應圖片時,觸發(fā)onclick事件并回調(diào)onRotate方法。

< !-- index.html -- >
< div class="space-around-row adjust-width crop-height" >
    < !-- 逆時針旋轉(zhuǎn) -- >
    < image src="http://www.nxhydt.com/images/chaijie_default.png" class="edit-image" onclick="onRotate(-90)" >< /image >
    < !-- 順時針旋轉(zhuǎn) -- >
    < image src="http://www.nxhydt.com/images/chaijie_default.png" class="edit-image" onclick="onRotate(90)" >< /image >
< /div >

在index.js文件中,實現(xiàn)onRotate方法。根據(jù)方法入?yún)ngle,調(diào)用PixelMap接口提供的rotate方法,完成圖片旋轉(zhuǎn)功能。

// index.js
export default {
  // 點擊逆時針旋轉(zhuǎn)
  onRotate(angle) {
    let that = this;
    this.postState = true;
    rotate(this.imagePixelMapAdjust, angle, () = > {
      that.exchange();
    });
  }
}
// rotateUtil.js
export async function rotate(pixelMap, angle, callback) {
  if (!pixelMap) {
    return;
  }
  await pixelMap.rotate(angle);
  callback();
}

圖片色域調(diào)節(jié)

本篇Codelab的色域調(diào)節(jié)是使用色域模型RGB-HSV來實現(xiàn)的。

  • RGB:是我們接觸最多的顏色空間,分別為紅色(R)、綠色(G)和藍色(B)。
  • HSV:是用色相H,飽和度S,明亮度V來描述顏色的變化
    • H:色相H取值范圍為0°~360°,從紅色開始按逆時針方向計算,紅色為0°,綠色為120°,藍色為240°。
    • S:飽和度S越高,顏色則深而艷。光譜色的白光成分為0,飽和度達到最高。通常取值范圍為0%~100%,值越大,顏色越飽和。
    • V:明度V表示顏色明亮的程度,對于光源色,明度值與發(fā)光體的光亮度有關;對于物體色,此值和物體的透射比或反射比有關。通常取值范圍為0%(黑)到100%(白)。

亮度調(diào)節(jié)

完成以下步驟實現(xiàn)亮度調(diào)節(jié):

  1. 將PixelMap轉(zhuǎn)換成ArrayBuffer。
  2. 將生成好的ArrayBuffer發(fā)送到worker線程。
  3. 對每一個像素點的亮度值按倍率計算。
  4. 將計算好的ArrayBuffer發(fā)送回主線程。
  5. 將ArrayBuffer寫入PixelMap,重新繪圖。

說明: 當前亮度調(diào)節(jié)是在UI層面實現(xiàn)的,未實現(xiàn)細節(jié)優(yōu)化算法,只做簡單示例。調(diào)節(jié)后的圖片會有色彩上的失真。

// index.js
export default {
  // pixelMap轉(zhuǎn)換ArrayBuffer及發(fā)送ArrayBuffer到worker,
  postToWorker(type, value, workerName) {
    let sliderValue = type === CommonConstants.AdjustId.BRIGHTNESS ? this.brightnessValue : this.saturationValue;
    this.workerInstance = new worker.ThreadWorker(workerName);
    const bufferArray = new ArrayBuffer(this.imagePixelMapAdjust.getPixelBytesNumber());
    this.imagePixelMapAdjust.readPixelsToBuffer(bufferArray).then(() = > {
      let message = new MessageItem(bufferArray, sliderValue, value);
      this.workerInstance.postMessage(message);
      this.postState = true;
      // 收到worker線程完成的消息
      this.workerInstance.onmessage = this.updatePixelMap.bind(this);
      this.workerInstance.onexit = () = > {
        if (type === CommonConstants.AdjustId.BRIGHTNESS) {
          this.brightnessValue = Math.floor(value);
        } else {
          this.saturationValue = Math.floor(value);
        }
      }
    });
  }
}
// AdjustBrightnessWork.js
// worker線程處理部分
workerPort.onmessage = function (event) {
  let bufferArray = event.data.buffer;
  let lastValue = event.data.lastValue;
  let currentValue = event.data.currentValue;
  let buffer = adjustImageValue(bufferArray, lastValue, currentValue);
  workerPort.postMessage(buffer);
}
// adjustUtil.js
// 倍率計算部分
export function adjustImageValue(bufferArray, last, cur) {
  return execColorInfo(bufferArray, last, cur, CommonConstants.HSVIndex.VALUE);
}

透明度調(diào)節(jié)

PixelMap接口提供了圖片透明度調(diào)節(jié)的功能。拖動滑塊調(diào)節(jié)透明度,回調(diào)setOpacityValue方法,獲取需要調(diào)節(jié)的透明度,最后調(diào)用opacity方法完成透明度調(diào)節(jié)。

// index.js
export default {
  setOpacityValue(event) {
    let slidingOpacityValue = event.value;
    let slidingMode = event.mode;
    if (slidingMode === CommonConstants.SLIDER_MODE_END || slidingMode === CommonConstants.SLIDER_MODE_CLICK) {
      adjustOpacity(this.imagePixelMapAdjust, slidingOpacityValue).then(pixelMap = > {
        this.imagePixelMapAdjust = pixelMap;
        this.drawToCanvas(this.imagePixelMapAdjust, this.drawImageLeft, this.drawImageTop,
          this.drawWidth, this.drawHeight);
        this.opacityValue = Math.floor(slidingOpacityValue);
      });
    }
  }
}
// opacityUtil.js
export async function adjustOpacity(pixelMap, value) {
  if (!pixelMap) {
    return;
  }
  pixelMap.opacity(parseInt(value) / CommonConstants.SLIDER_MAX_VALUE).catch(err = > {
    Logger.error(`opacity err ${JSON.stringify(err)}`);
  });
  return pixelMap;
}

飽和度調(diào)節(jié)

飽和度調(diào)節(jié)與亮度調(diào)節(jié)步驟類似:

  1. 將PixelMap轉(zhuǎn)換成ArrayBuffer。
  2. 將生成好的ArrayBuffer發(fā)送到worker線程。
  3. 對每一個像素點的飽和度值按倍率計算。
  4. 將計算好的ArrayBuffer發(fā)送回主線程。
  5. 將ArrayBuffer寫入PixelMap,重新繪圖。

說明: 當前飽和度調(diào)節(jié)是在UI層面實現(xiàn)的,未實現(xiàn)細節(jié)優(yōu)化算法,只做簡單示例。調(diào)節(jié)后的圖片會有色彩上的失真。

// index.js
export default {
  // pixelMap轉(zhuǎn)換ArrayBuffer及發(fā)送ArrayBuffer到worker,
  postToWorker(type, value, workerName) {
    let sliderValue = type === CommonConstants.AdjustId.BRIGHTNESS ? this.brightnessValue : this.saturationValue;
    this.workerInstance = new worker.ThreadWorker(workerName);
    const bufferArray = new ArrayBuffer(this.imagePixelMapAdjust.getPixelBytesNumber());
    this.imagePixelMapAdjust.readPixelsToBuffer(bufferArray).then(() = > {
      let message = new MessageItem(bufferArray, sliderValue, value);
      this.workerInstance.postMessage(message);
      this.postState = true;
      // 收到worker線程完成的消息
      this.workerInstance.onmessage = this.updatePixelMap.bind(this);
      this.workerInstance.onexit = () = > {
        if (type === CommonConstants.AdjustId.BRIGHTNESS) {
          this.brightnessValue = Math.floor(value);
        } else {
          this.saturationValue = Math.floor(value);
        }
      }
    });
  }
}
// adjustSaturationWork.js
// worker線程處理部分
workerPort.onmessage = function (event) {
  let bufferArray = event.data.buffer;
  let lastValue = event.data.lastValue;
  let currentValue = event.data.currentValue;
  let buffer = adjustSaturation(bufferArray, lastValue, currentValue)
  workerPort.postMessage(buffer);
}
// adjustUtil.js
// 倍率計算部分
export function adjustSaturation(bufferArray, last, cur) {
  return execColorInfo(bufferArray, last, cur, CommonConstants.HSVIndex.SATURATION);
}

審核編輯 黃宇

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

    關注

    0

    文章

    16

    瀏覽量

    10959
  • 鴻蒙
    +關注

    關注

    56

    文章

    2267

    瀏覽量

    42493
  • HarmonyOS
    +關注

    關注

    79

    文章

    1946

    瀏覽量

    29742
  • OpenHarmony
    +關注

    關注

    25

    文章

    3549

    瀏覽量

    15749
收藏 人收藏

    評論

    相關推薦

    TL3588-視頻開發(fā)案

    TL3588-視頻開發(fā)案
    的頭像 發(fā)表于 01-24 16:29 ?569次閱讀
    TL3588-視頻<b class='flag-5'>開發(fā)案</b>例

    3568F-視頻開發(fā)案

    3568F-視頻開發(fā)案
    的頭像 發(fā)表于 04-12 13:51 ?752次閱讀
    3568F-視頻<b class='flag-5'>開發(fā)案</b>例

    51單片機應用開發(fā)案例精選(代碼及圖片

    《51單片機應用開發(fā)案例精選》分為3部分。第1部分(第1章)講解單片機開發(fā)的預備知識,簡要介紹了單片機的開發(fā)流程、開發(fā)工具和最小系統(tǒng);第2部分(第2章~第3章)講解單片機
    發(fā)表于 01-09 16:16

    HarmonyOS IoT 硬件開發(fā)案例分享

    ``許思維老師HiSpark Wi-Fi IoT 開發(fā)案例分享:案例一:AHT20溫濕度傳感器開發(fā)、調(diào)試;案例二:oled屏驅(qū)動庫移植,調(diào)試;案例三:用OLED屏播放視頻,Wi-Fi 和 TCP/IP 綜合應用。 ``
    發(fā)表于 10-27 17:30

    HarmonyOS HiSpark Wi-Fi IoT套件】HarmonyOS IoT 硬件開發(fā)案例分享

    HiSpark Wi-Fi IoT 開發(fā)案例分享:案例一:AHT20溫濕度傳感器開發(fā)、調(diào)試;案例二:oled屏驅(qū)動庫移植,調(diào)試;案例三:用OLED屏播放視頻,Wi-Fi 和 TCP/IP 綜合應用。
    發(fā)表于 10-27 19:12

    【潤和直播課預告@華為開發(fā)者學院】HarmonyOS設備開發(fā)基礎課程|HiSpark WiFi-IoT 智能小車套件開發(fā)案

    `【潤和直播課預告@華為開發(fā)者學院】HarmonyOS設備開發(fā)基礎課程|HiSparkWiFi-IoT 智能小車套件開發(fā)案例,3月18日(周四) 19:00-21:00,讓你的
    發(fā)表于 03-16 15:01

    HarmonyOS教程—基于圖片處理能力,實現(xiàn)一個圖片編輯模板

    :界面UI和圖片編輯器。模板界面UI部分主要為開發(fā)者提供了:圖片編輯界面的設計參考,以及HarmonyO
    發(fā)表于 08-31 10:13

    51單片機應用開發(fā)案例精選-源代碼

    本內(nèi)容提供了51單片機應用開發(fā)案例精選-源代碼及開發(fā)圖片
    發(fā)表于 08-10 09:40 ?536次下載
    51單片機應用<b class='flag-5'>開發(fā)案</b>例精選-源代碼

    許思維老師HarmonyOS IoT硬件開發(fā)案例分享

    許思維老師HiSpark Wi-Fi IoT 開發(fā)案例分享:案例一:AHT20溫濕度傳感器開發(fā)、調(diào)試;案例二:oled屏驅(qū)動庫移植,調(diào)試;案例三:用OLED屏播放視頻,Wi-Fi 和 TCP/IP 綜合應用。
    發(fā)表于 10-29 10:39 ?39次下載
    許思維老師<b class='flag-5'>HarmonyOS</b> IoT硬件<b class='flag-5'>開發(fā)案</b>例分享

    華為開發(fā)HarmonyOS零基礎入門:Word圖片資源支持預覽效果

    華為開發(fā)HarmonyOS零基礎入門:Word圖片資源支持預覽效果,list主鍵函數(shù)可以做布局,呈現(xiàn)多個堆疊顯示效果。
    的頭像 發(fā)表于 10-23 10:12 ?1401次閱讀
    華為<b class='flag-5'>開發(fā)</b>者<b class='flag-5'>HarmonyOS</b>零基礎入門:Word<b class='flag-5'>圖片</b>資源支持預覽效果

    華為開發(fā)者分論壇HarmonyOS學生公開課-OpenHarmony Codelabs開發(fā)案

    2021華為開發(fā)者分論壇HarmonyOS學生公開課-OpenHarmony Codelabs開發(fā)案
    的頭像 發(fā)表于 10-24 11:25 ?1812次閱讀
    華為<b class='flag-5'>開發(fā)</b>者分論壇<b class='flag-5'>HarmonyOS</b>學生公開課-OpenHarmony Codelabs<b class='flag-5'>開發(fā)案</b>例

    OpenHarmony上實現(xiàn)圖片編輯功能

    圖片編輯是在應用中經(jīng)常用到的功能,比如相機拍完照片后可以對照片進行編輯;截圖后可以對截圖進行編輯;可以對圖庫中的圖片進行
    的頭像 發(fā)表于 06-25 15:17 ?1061次閱讀
    OpenHarmony上實現(xiàn)<b class='flag-5'>圖片</b><b class='flag-5'>編輯</b>功能

    RK3568---NPU開發(fā)案

    RK3568---NPU開發(fā)案
    的頭像 發(fā)表于 01-19 13:50 ?673次閱讀
    RK3568---NPU<b class='flag-5'>開發(fā)案</b>例

    HarmonyOS開發(fā)實例:【圖片編輯應用】

    通過動態(tài)設置元素樣式的方式,實現(xiàn)幾種常見的圖片操作,包括裁剪、旋轉(zhuǎn)、縮放和鏡像。
    的頭像 發(fā)表于 04-23 09:42 ?323次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發(fā)</b>實例:【<b class='flag-5'>圖片</b><b class='flag-5'>編輯</b>應用】

    HarmonyOS開發(fā)案例:【圖片編輯

    基于ArkTS的聲明式開發(fā)范式的樣例,主要介紹了圖片編輯實現(xiàn)過程。
    的頭像 發(fā)表于 04-23 20:54 ?239次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發(fā)案</b>例:【<b class='flag-5'>圖片</b><b class='flag-5'>編輯</b>】