写点什么

基于 ArkUI 开发框架,图片马赛克处理的实现

  • 2022 年 5 月 31 日
  • 本文字数:2589 字

    阅读完需:约 8 分钟

基于ArkUI开发框架,图片马赛克处理的实现

关于马赛克


马赛克是一种使用较为广泛的图片处理方式,通过将图片特定区域的色阶细节劣化、色块打乱让图片模糊化,常用来遮挡图片中的重要信息及隐私内容。本期,我们将通过图像的基础知识帮助大家了解图片马赛克处理的原理,同时给大家带来 ArkUI 开发框架中图片马赛克处理的实现。



一、图像基础


了解图片的像素以及分辨率等基础知识,有助于后文对马赛克原理的理解。


1. 像素

像素(英文名:pixel,简称 px)是图片的最小单位,每张图片都是由无数的像素点组成。如图 1 所示,每个小方格就是一个个的像素点,每个像素点都具有明确的位置坐标和色彩数值,像素点的位置和颜色共同决定该图片所呈现出来的样子。


图 1 像素点


在计算机中,每个像素点的色彩数值都是通过 RGB 通道来控制,RGB 即三原色:红 Red,绿 Green,蓝 Blue 的通道,这三种色彩混合叠加,几乎能形成人类视力所能感知的所有颜色。由此,设置图片中每个像素的 RGB 通道分量值,并根据特有的算法或者滤波器,便可让像素呈现任何颜色。


图 2 光学三原色


2. 分辨率

分辨率是图片在长和宽上各拥有的像素,分辨率越高,所包含的像素就越多,图片就越清晰。如图 3 所示,是一张分辨率为 12*14 的图片,由横向 12 个像素点和纵向 14 个像素点构成,共包含了 12*14 个像素点。不难发现,由于分辨率比较低,我们甚至无法辨别图片的内容。


图 3 低分辨率图片


如图 4 所示,通过不断增大图片的分辨率,不难看出,图片的清晰度越来越高。


图 4 分辨率的变化


二、马赛克原理


增大图片的分辨率可以让图片变得更清晰,那么我们是不是可以降低图片的分辨率来让图片变模糊?


马赛克的原理就是降低原图片的分辨率。如图 5 所示,首先我们将原图分割成若干个大小一致的小方格,然后获取每个小方格中的像素点的平均色彩数值,最后使用获取到的平均色彩数值替换该方格中所有的像素点,即可实现图片的马赛克处理。


图 5 马赛克原理


同时,我们还可以控制图片中小方格的个数来实现马赛克的强弱,如图 6 所示。


图 6 马赛克强弱控制


三、马赛克实现


相信大家已经熟悉了马赛克的原理,下面我们将以全马赛克图片为例,为大家介绍基于 ArkUI 开发框架的马赛克的具体实现。


1. 首先我们需获取 ArkUI 开发框架的 image 能力,该能力提供了图片开发的基本接口。


import image from "@ohos.multimedia.image"
复制代码


2. 通过 readPixelsToBuffer 接口,一次性读取图片中所有的像素点数据,每个像素点数据都包含了 RGB 通道的分量值(如 Red:18、Green:250、Blue:20)。


let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber());await bitmap.readPixelsToBuffer(bufferData);
复制代码


其中 ArrayBuffer 里面缓存的像素点数据主要包括 RGB 通道的分量值及图片透明度,参考代码如下:


for (let index = 0; index < dataArray.length; index += 4) {   const r = dataArray[index];   const g = dataArray[index+1];   const b = dataArray[index+2];   const a = dataArray[index+3];}
复制代码


3. 根据自定义的单个小方格的 Width 和 Height,将整个图片分成若干小方格。


//横排的正方形个数var x_index = Math.floor(targetWidth / realPixel_W);//纵排的正方形个数var y_index = Math.floor(targetHeight / realPixel_H);
复制代码


4. 获取每个小方格左上角的最大坐标及右下角的最小坐标,以确定小方格的区域。并根据每个小方格内的所有像素点数据统一该区域的像素,统一方式可以是取该区域内像素点的平均值,或者随机选取一个像素。



参考代码如下:

for (let ch = 0; ch < y_index; ch++) { for (let cw = 0; cw < x_index; cw++) {    let max_x = (cw + 1) * realPixel_W > targetWidth ? targetWidth : (cw + 1) * realPixel_W;    let max_y = (ch + 1) * realPixel_H > targetHeight ? targetHeight : (ch + 1) * realPixel_H;    let min_x = cw * realPixel_W;    let min_y = ch * realPixel_H;    //取左上角的像素值    let center_p = inPixels[min_y+1][min_x+1];    //设置该正方形里的像素统一    for (let zh = min_y; zh < max_y; zh++) {      for (let zw = min_x; zw < max_x; zw++) {        inPixels[zh][zw] = center_p;      }    }  }}
复制代码


5. 通过 writeBufferToPixels 接口,将统一的像素点数据缓存到 ArrayBuffer 中,并写入 PixelMap,由此得到整张马赛克处理的图片。


writeBufferToPixels(src: ArrayBuffer): Promise<void>
复制代码


四、涂鸦马赛克


通过上文的介绍,相信大家已经基本掌握了马赛克的实现。下面我们将为大家带来马赛克开发的具体实例“涂鸦马赛克”,即可以根据手指滑动的轨迹,生成对应的马赛克区域。本文仅提供实现思路及关键代码,感兴趣的小伙伴可结合上文的介绍补全代码。


1. 给图片添加 Touch 事件,获取手指的运动轨迹。参考代码如下:


Image(this._mCropPixelMap.pixelMap)  .width(300)  .height(300)  .margin(10)  .objectFit(ImageFit.Contain)  .onTouch(event => {    let array: TouchObject[] = event.changedTouches;    for (let i = 0;i < array.length; i++) {      //触摸的x y坐标      let centX = array[i].x;      let centY = array[i].y;    }  });
复制代码


2. 根据运动轨迹,以触摸点的坐标(x,y)为中心,根据自定义小方格的大小,动态确认马赛克区域的位置。参考代码如下:


//获取到左上角的坐标let offMinX = Math.floor(centerX - pixel / 2);let offMinY = Math.floor(centerY - pixel / 2);//右下角的坐标let offMaxX = Math.floor(centerX + pixel / 2);let offMaxY = Math.floor(centerY + pixel / 2);offMinX = offMinX < 0 ? 0 : offMinX;offMinY = offMinY < 0 ? 0 : offMinY;offMaxX = offMaxX > targetWidth ? targetWidth : offMaxX;offMaxY = offMaxY > targetHeight ? targetHeight : offMaxY;
复制代码


3. 统一马赛克区域的所有的像素点值。


//取左上角的像素值let center_p = PixelExampleUtils.inPixels[offMaxY+1][offMaxX+1];//设置该正方形里的像素统一for (let zh = offMinY; zh < offMaxY; zh++) {  for (let zw = offMinX; zw < offMaxX; zw++) {    PixelExampleUtils.inPixels[zh][zw] = center_p;    changeArray[zh][zw] = center_p;  }}
复制代码


4. 最后将更改的像素点写入图片中,即可得到手指滑动轨迹的马赛克图片。


以上就是本期全部内容,恭喜你花几分钟时间获得了一个实用的技能。期待广大开发者能开发出更多有趣的马赛克应用。



发布于: 刚刚阅读数: 3
用户头像

每一位开发者都是华为要汇聚的星星之火 2021.10.15 加入

提供HarmonyOS关键技术解析、版本更新、开发者实践和活动资讯,欢迎各位开发者加入HarmonyOS生态,一起创造无限可能!

评论

发布
暂无评论
基于ArkUI开发框架,图片马赛克处理的实现_HarmonyOS_HarmonyOS开发者社区_InfoQ写作社区