二维码实际上就是字符串,用来记录信息的,由点组成,下面我们来构建个性化的二维码
1.第一步:创建原始二维码
+(CIImage *)Create_Original_CIImageWithString:(NSString *)str{
CIFilter *filter = [CIFilterfilterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKeyPath:@"inputMessage"];
[filter setValue:@"H"forKey:@"inputCorrectionLevel"];
CIImage *outputImage = [filter outputImage];
return outputImage;
}
2.第二步:将原始图片的所有点的色值保存到二维数组
+(NSArray<NSArray >)getPixelsWithCIImage:(CIImage *)ciimg{
NSMutableArray *pixels = [NSMutableArrayarray];
CGImageRef imageRef = [selfconvertCIImage2CGImageForCIImage:ciimg];
CGFloat width = CGImageGetWidth(imageRef);
CGFloat height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsignedchar *rawData = (unsignedchar *)calloc(height * width * 4, sizeof(unsignedchar));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = width * bytesPerPixel;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
for (int indexY = 0; indexY < height; indexY++) {
NSMutableArray *tepArrM = [NSMutableArrayarray];
for (int indexX = 0; indexX < width; indexX++) {
@autoreleasepool {
NSUInteger byteIndex = bytesPerRow * indexY + indexX * bytesPerPixel;
CGFloat alpha = (CGFloat)rawData[byteIndex + 3];
CGFloat red = (CGFloat)rawData[byteIndex];
CGFloat green = (CGFloat)rawData[byteIndex + 1];
CGFloat blue = (CGFloat)rawData[byteIndex + 2];
structJPIntPixel pixel;
pixel.alpha = alpha;
pixel.red = red;
pixel.green = green;
pixel.blue = blue;
NSValue *value = [NSValuevalueWithBytes:&pixel objCType:@encode(structJPIntPixel)];
[tepArrM addObject:value];
byteIndex += bytesPerPixel;
}
}
[pixels addObject:[tepArrM copy]];
}
free(rawData);
return [pixels copy];
}
3.第三步:判断每个点是否有颜色色值,截取有色值的点,重新创建数组
+(NSArray<NSArray >)handlePointsShouldDisplayCodeForArr:(NSArray<NSArray >)pixels{
NSMutableArray *results = [NSMutableArrayarrayWithCapacity:pixels.count];
for (int indexY = 0; indexY < pixels.count; indexY++) {
NSMutableArray *tepArrM = [NSMutableArrayarrayWithCapacity:pixels[indexY].count];
for (int indexX = 0; indexX < pixels[indexY].count; indexX++) {
@autoreleasepool {
NSValue *value = pixels[indexY][indexX];
structJPIntPixel pixel;
[value getValue:&pixel];
BOOL shouldDisplay = pixel.red == 0 && pixel.green == 0 && pixel.blue == 0;
[tepArrM addObject:@(shouldDisplay)];
}
}
[results addObject:[tepArrM copy]];
}
return [results copy];
}
拿到具有信息量的点集合后,我们就可以自定义我们的二维码了
在此,我设置了kQRCodeSizeType枚举,用来标识点的大小
typedefNS_ENUM(NSInteger, kQRCodeSizeType) {
kQR_Size_Small=1,
kQR_Size_Normal,
kQR_Size_Big
};
设置了kQRCodeDrawType枚举,用来标识点的形状,其中加入了图标自定义
typedefNS_ENUM(NSInteger, kQRCodeDrawType) {
kQR_Draw_None=1,
kQR_Draw_Square, // 正方形
kQR_Draw_Circle, // 圆
kQR_Draw_Icon // 图标
};
设置了kQRCodeGradientType枚举,用来标识点渐变
typedefNS_ENUM(NSInteger, kQRCodeGradientType) {
kQR_Gradient_None=1, // 纯色
kQR_Gradient_Horizontal, // 水平渐变
kQR_Gradient_Diagonal, // 对角线渐变
};
下面我们来看效果:
这是一个正方形、对角线渐变的二维码
这是一个正方形、水平渐变的二维码
这是一个圆形、对角线渐变的二维码
还有图标组成的
欢迎下载源码,相互交流:https://git.oschina.net/VanCamp/wkqr.git
或者扫描二维码和我交流,蟹蟹O(∩_∩)O
网友评论