iOS 定制多样式二维码

2020-01-18 22:02:52刘景俊

相较于前面的代码,多了两个步骤:判断rgb的有效值;对二维码进行颜色渲染。颜色渲染的过程包括获取图像的位图上下文、像素替换、二进制图像转换等操作,具体代码如下:


/*! 对生成二维码图像进行颜色填充*/
+ (UIImage *)imageFillBlackColorAndTransparent: (UIImage *)image red: (NSUInteger)red green: (NSUInteger)green blue: (NSUInteger)blue {

 const int imageWidth = image.size.width;
 const int imageHeight = image.size.height;
 size_t bytesPerRow = imageWidth * 4;
 uint32_t * rgbImageBuf = (uint32_t *)malloc(bytesPerRow * imageHeight);

 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
 CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
 CGContextDrawImage(context, (CGRect){(CGPointZero), (image.size)}, image.CGImage);

 //遍历像素
 int pixelNumber = imageHeight * imageWidth;
 [self fillWhiteToTransparentOnPixel: rgbImageBuf pixelNum: pixelNumber red: red green: green blue: blue];
 CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow, ProviderReleaseData);
 CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider, NULL, true, kCGRenderingIntentDefault);

 UIImage * resultImage = [UIImage imageWithCGImage: imageRef]; 
 CGImageRelease(imageRef);
 CGColorSpaceRelease(colorSpace);
 CGContextRelease(context);
 return resultImage;
}

/! 遍历所有像素点进行颜色替换/
+ (void)fillWhiteToTransparentOnPixel: (uint32_t *)rgbImageBuf pixelNum: (int)pixelNum red: (NSUInteger)red green: (NSUInteger)green blue: (NSUInteger)blue {
uint32_t * pCurPtr = rgbImageBuf;
for (int i = 0; i < pixelNum; i++, pCurPtr++) {
    if ((*pCurPtr & 0xffffff00) < 0xd0d0d000) {
      uint8_t * ptr = (uint8_t *)pCurPtr;
      ptr[3] = red;
      ptr[2] = green;
      ptr[1] = blue;
    } else {
      //将白色变成透明色
      uint8_t * ptr = (uint8_t *)pCurPtr;
      ptr[0] = 0;
    }
  }
}

void ProviderReleaseData(void * info, const void * data, size_t size) {
  free((void *)data);
}

ps:在修改代码之前,应该想清楚是否需要删除原有代码。类似这种二维码的扩展,旧的二维码生成接口可以留下来,然后在其中调用多参数的全能构造器Designated Initializer。

ios,二维码

这时候距离微信还差一小步,我们要在二维码的中心位置插入我们的小头像,最直接的方式是加载完我们的头像后,直接drawInRect:这种实现方法是正确的,但是在我们画上去之前,我们还需要对图像进行圆角处理。(省事的可能直接用imageView加载头像,然后设置头像的cornerRadius,这个也能实现效果)。