原文:https://mp.weixin.qq.com/s/60HDKcBFV7GTjZpzeHtjeg,点击链接查看更多技术内容。
 
 
关于马赛克
 
马赛克是一种使用较为广泛的图片处理方式,通过将图片特定区域的色阶细节劣化、色块打乱让图片模糊化,常用来遮挡图片中的重要信息及隐私内容。本期,我们将通过图像的基础知识帮助大家了解图片马赛克处理的原理,同时给大家带来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. 最后将更改的像素点写入图片中,即可得到手指滑动轨迹的马赛克图片。
 
以上就是本期全部内容,恭喜你花几分钟时间获得了一个实用的技能。期待广大开发者能开发出更多有趣的马赛克应用。
 

 

基于ArkUI开发框架,图片马赛克处理的实现的更多相关文章

  1. 基于HTML5 Canvas实现的图片马赛克模糊特效

    效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...

  2. 基于纹理的图片检索及demo(未启动)

    基于纹理的图片检索及demo(未启动)

  3. 基于h5的图片无刷新上传(uploadifive)

    基于h5的图片无刷新上传(uploadifive) uploadifive简介 了解uploadify之前,首先了解来一下什么是uploadify,uploadfy官网,uploadify和uploa ...

  4. 基于jQuery的图片相册滑出放大插件

    今天给大家带来一款基于jQuery的图片相册滑出放大插件.点击相册图片,展示该图片.该插件适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗..效 ...

  5. 如何基于Winform开发框架或混合框架基础上进行项目的快速开发

    在开发项目的时候,我们为了提高速度和质量,往往不是白手起家,需要基于一定的基础上进行项目的快速开发,这样可以利用整个框架的生态基础模块,以及成熟统一的开发方式,可以极大提高我们开发的效率.本篇随笔就是 ...

  6. HTML5_canvas_像素操作_图片马赛克_图片反相

    canvas 像素操作 像素,即像素点,一个像素只有一个颜色 100*100 的 px 的屏幕区域有 100*100*4 个像素点,即 width*height*4 rgba(0, 0, 0, 1); ...

  7. 一款基于jQuery的图片场景标注提示弹窗特效

    今天给大家分享一款基于jQuery的图片场景标注提示弹窗特效,这款实例适合在图片上标注某个物件,单击弹出详情说明,兼容360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之 ...

  8. 基于jquery hover图片遮罩层滑动

    分享一款基于jquery hover图片遮罩层滑动.这是一款仿腾讯课堂的鼠标悬停经过图片遮罩透明层滑动效果.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div clas ...

  9. 基于jQuery悬停图片变色放大特效

    分享一款基于jQuery悬停图片变色放大特效是一款响应式鼠标悬停图片放大效果代码.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div style="width ...

  10. 基于html5背景图片自适应代码

    基于html5背景图片自适应代码是一款背景不随滚动条滚动,会根据分辨率不同自动匹配对应的背景图片.效果图如下: 在线预览   源码下载 实现的代码. css代码: .jawbone-hero .jaw ...

随机推荐

  1. Mysql基础目录

    尚硅谷Mysql课程笔记 课程链接: https://www.bilibili.com/video/BV1iq4y1u7vj?p=1 第01章_数据库概述 第02章_MySQL环境搭建 第03章_基本 ...

  2. InputNumber 不能输入点 viewDesign 需求是 只能是整数

    <InputNumber ref="xxxRef" v-model="xxx" :disabled="xxx" style=" ...

  3. 软件推荐: Sourcetree git软件

    注意事项: 破解的时候,json文件目录不是软件exe所在目录,是数据目录 %LocalAppData%\Atlassian\SourceTree 还有就是第一次运行弹出个 有个插件要不要用,选第3个 ...

  4. 掌握python的dataclass,让你的代码更简洁优雅

    dataclass是从Python3.7版本开始,作为标准库中的模块被引入.随着Python版本的不断更新,dataclass也逐步发展和完善,为Python开发者提供了更加便捷的数据类创建和管理方式 ...

  5. 07.Android之多媒体问题

    目录介绍 7.0.0.1 加载bitmap图片的时候需要注意什么?为何bitmap容易造成OOM?如何计算Bitmap占用内存? 7.0.0.2 如何理解recycle释放内存问题?图片加载到内存其实 ...

  6. Install fail! SyntaxError: Unexpected token 'h', "hub.com>","... is not valid JSON (file: C:\Users\Admin\Documents\uirecorder_test\node_modules\_mocha@5.2.0@mocha\package.json)

    uirecorder初始化时解析错误: PS C:\Users\Admin\Documents\uirecorder_test> PS C:\Users\Admin\Documents\uire ...

  7. 记录--JS-SDK页面打开提示realAuthUrl错误

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 测试环境好好地功能,上了生产,莫名其妙报错,开始以为是没有设置Js安全接口域名,结果让相应人员一查,已经设置了相应的域名,再看下公众号内的 ...

  8. k8s-master 设置调度污点

    k8s master 调度污点 NoSchedule:K8Snode添加这个effecf类型污点,新的不能容忍的pod不能再调度过来,但是老的运行在node上不受影响 NoExecute:K8Snod ...

  9. 靶场搭建----phpstudy2018安装及注意问题

    安装 官网下载: https://www.xp.cn/download.html 新人推荐2018 版本phpstudy 介绍 系统服务------开机自启 非服务模式------开机不自启 搭建好环 ...

  10. 一文讲透Java核心技术之高可扩展利器SPI

    大家好,我是冰河~~ SPI的概念 JAVA SPI = 基于接口的编程+策略模式+配置文件 的动态加载机制 SPI的使用场景 Java是一种面向对象语言,虽然Java8开始支持函数式编程和Strea ...