图片马赛克原理下图所示:
图片是由一个个像素组成,每个红框表示一个像素,每一个像素都有一个RGBA的值,这里随便用一写字母表示其颜色值。
这里拿马赛克大小为3个像素宽度举例,如果设置为3个像素宽度的马赛克处理,则每次手机会处理3*3共9个像素的矩阵,将这9个像素值处理成与矩阵第一个像素的值相等的像素值,然后重新填充矩阵像素值。每次从左到右,从上到下,以步长为3个像素,去处理每个3*3的像素矩阵,将这9个像素值处理成与矩阵第一个像素的值相等的像素值,直到将整个图片的像素处理完成,生成马赛克图片。
下图为原图与处理后生成的二维码图片
原图 马赛克图片上代码:
创建一个ImageUtils类,提供一个将原图转换成马赛克图片的方法
ImageUtils.h的代码如下,需要导入OpenCV的一些文件,
#import <UIKit/UIKit.h>
//导入OpenCV框架
//核心头文件
#import <opencv2/opencv.hpp>
//对ios支持
#import <opencv2/imgcodecs/ios.h>
//导入矩阵帮助类
#import <opencv2/highgui.hpp>
#import <opencv2/core/types.hpp>
//导入C++命名空间
using namespace cv;
@interface ImageUtils:NSObject
//定义方法:处理图片
+(UIImage*)opencvImage:(UIImage*)image level:(int)level;
@end
因为用到了C++,所以ImageUtils.m也要改成ImageUtils.mm,ImageUtils.mm的实现如下
#import "ImageUtils.h"
@implementation ImageUtils
+(UIImage*)opencvImage:(UIImage*)image level:(int)level{
//实现功能
//第一步:将iOS图片->OpenCV图片(Mat矩阵)
Mat mat_image_src;
UIImageToMat(image, mat_image_src);
//第二步:确定宽高
int width = mat_image_src.cols;
int height = mat_image_src.rows;
//图片类型->进行转换
//在OpenCV里面
//坑隐藏
//支持->RGB处理
//图片ARGB
//将ARGB->RGB
Mat mat_image_dst;
//一定要记得转换类型
cvtColor(mat_image_src, mat_image_dst, CV_RGBA2RGB, 3);
//为了不影响原始图片
Mat mat_image_clone = mat_image_dst.clone();
//第三步:马赛克处理
//分析马赛克算法原理
//level = 3-> 3 * 3矩形
//动态的处理
int x = width - level;
int y = height - level;
for (int i = 0; i < y; i += level) {
for (int j = 0; j < x; j += level) {
//创建一个矩形区域
Rect2i mosaicRect = Rect2i(j, i, level, level);
//给填Rect2i区域->填充数据->原始数据
Mat roi = mat_image_dst(mosaicRect);
//让整个矩形区域颜色值保持一致
//mat_image_clone.at(i, j)->像素点(颜色值组成->多个)->ARGB->数组
//mat_image_clone.at(i, j)[0]->R值
//mat_image_clone.at(i, j)[1]->G值
//mat_image_clone.at(i, j)[2]->B值
Scalar scalar = Scalar(
mat_image_clone.at(i, j)[0],
mat_image_clone.at(i, j)[1],
mat_image_clone.at(i, j)[2]);
//将处理好矩形区域->数据->拷贝到图片上面去->修改后的数据
//CV_8UC3解释一下->后面也会讲到
//CV_:表示框架命名空间
//8表示:32位色->ARGB->8位 = 1字节 -> 4个字节
//U分析
//两种类型:有符号类型(Sign->有正负->简写"S")、无符号类型(Unsign->正数->"U")
//无符号类型:0-255(通常情况)
//有符号类型:-128-127
//C分析:char类型
//3表示:3个通道->RGB
Mat roiCopy = Mat(mosaicRect.size(), CV_8UC3, scalar);
roiCopy.copyTo(roi);
}
}
//第四步:将OpenCV图片->iOS图片
return MatToUIImage(mat_image_dst);
}
@end
调用ImageUtils相应的代码:
#import "ImageUtils.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//正常图片
- (IBAction)clickNormal:(id)sender {
_imageView.image = [UIImage imageNamed:@"girl.jpeg"];
}
//马赛克图片
- (IBAction)clickMosaic:(id)sender {
_imageView.image = [ImageUtils opencvImage:_imageView.image level:20];
}
@end
网友评论