共计 2851 个字符,预计需要花费 8 分钟才能阅读完成。
#### 对于马赛克
马赛克是一种应用较为宽泛的图片解决形式,通过将图片特定区域的色阶细节劣化、色块打乱让图片模糊化,罕用来遮挡图片中的重要信息及隐衷内容。本期,咱们将通过图像的基础知识帮忙大家理解图片马赛克解决的原理,同时给大家带来 ArkUI 开发框架中图片马赛克解决的实现。
** 一、图像根底 **
理解图片的像素以及分辨率等基础知识,有助于后文对马赛克原理的了解。
1. 像素
像素(英文名:pixel,简称 px)是图片的最小单位,每张图片都是由有数的像素点组成。如图 1 所示,每个小方格就是一个个的像素点,每个像素点都具备明确的地位坐标和色调数值,像素点的地位和色彩独特决定该图片所出现进去的样子。
图 1 像素点
在计算机中,每个像素点的色调数值都是通过 RGB 通道来管制,RGB 即三原色:红 Red,绿 Green,蓝 Blue 的通道,这三种色调混合叠加,简直能造成人类视力所能感知的所有色彩。由此,设置图片中每个像素的 RGB 通道重量值,并依据特有的算法或者滤波器,便可让像素出现任何色彩。
图 2 光学三原色
2. 分辨率
分辨率是图片在长和宽上各领有的像素,分辨率越高,所蕴含的像素就越多,图片就越清晰。如图 3 所示,是一张分辨率为 1214 的图片,由横向 12 个像素点和纵向 14 个像素点形成,共蕴含了 1214 个像素点。不难发现,因为分辨率比拟低,咱们甚至无奈分别图片的内容。
图 3 低分辨率图片
如图 4 所示,通过一直增大图片的分辨率,不难看出,图片的清晰度越来越高。
图 4 分辨率的变动
二、** 马赛克原理 **
增大图片的分辨率能够让图片变得更清晰,那么咱们是不是能够升高图片的分辨率来让图片变含糊?
马赛克的原理就是升高原图片的分辨率。如图 5 所示,首先咱们将原图宰割成若干个大小统一的小方格,而后获取每个小方格中的像素点的均匀色调数值,最初应用获取到的均匀色调数值替换该方格中所有的像素点,即可实现图片的马赛克解决。
图 5 马赛克原理
同时,咱们还能够管制图片中小方格的个数来实现马赛克的强弱,如图 6 所示。
图 6 马赛克强弱管制
** 三、马赛克实现 **
置信大家曾经相熟了马赛克的原理,上面咱们将以全马赛克图片为例,为大家介绍基于 ArkUI 开发框架的马赛克的具体实现。
- 首先咱们需获取 ArkUI 开发框架的 image 能力,该能力提供了图片开发的根本接口。
- 首先咱们需获取 ArkUI 开发框架的 image 能力,该能力提供了图片开发的根本接口。
- 通过 readPixelsToBuffer 接口,一次性读取图片中所有的像素点数据,每个像素点数据都蕴含了 RGB 通道的重量值(如 Red:18、Green:250、Blue:20)。
其中 ArrayBuffer 外面缓存的像素点数据次要包含 RGB 通道的重量值及图片透明度,参考代码如下: - 依据自定义的单个小方格的 Width 和 Height,将整个图片分成若干小方格。
- 获取每个小方格左上角的最大坐标及右下角的最小坐标,以确定小方格的区域。并依据每个小方格内的所有像素点数据对立该区域的像素,对立形式能够是取该区域内像素点的平均值,或者随机选取一个像素。
参考代码如下:
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;
}
}
}
}
-
通过 writeBufferToPixels 接口,将对立的像素点数据缓存到 ArrayBuffer 中,并写入 PixelMap,由此失去整张马赛克解决的图片。
** 四、涂鸦马赛克 **
通过上文的介绍,置信大家曾经根本把握了马赛克的实现。上面咱们将为大家带来马赛克开发的具体实例“涂鸦马赛克”,即能够依据手指滑动的轨迹,生成对应的马赛克区域。本文仅提供实现思路及要害代码,感兴趣的小伙伴可联合上文的介绍补全代码。
- 给图片增加 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;
}
});
- 依据静止轨迹,以触摸点的坐标(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;
- 对立马赛克区域的所有的像素点值。
// 取左上角的像素值
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;
}
}
- 最初将更改的像素点写入图片中,即可失去手指滑动轨迹的马赛克图片。
以上就是本期全部内容,祝贺你花几分钟工夫取得了一个实用的技能。期待宽广开发者能开发出更多乏味的马赛克利用。