iOS生成二维码(彩色 + 阴影)

作者: 船长_ | 来源:发表于2015-12-10 19:55 被阅读4629次

    1.二维码基本设置

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 1.创建滤镜
        CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
        
        // 2.还原滤镜默认属性
        [filter setDefaults];
        
        // 3.设置需要生成二维码的数据到滤镜中
        // OC中要求设置的是一个二进制数据
        NSData *data = [@"http://www.jianshu.com/p/05949cc8f7af" dataUsingEncoding:NSUTF8StringEncoding];
        [filter setValue:data forKeyPath:@"InputMessage"];
        
        // 4.从滤镜从取出生成好的二维码图片
        CIImage *ciImage = [filter outputImage];
        
        self.customImageView.layer.shadowOffset = CGSizeMake(0, 0.5);  // 设置阴影的偏移量
        self.customImageView.layer.shadowRadius = 1;  // 设置阴影的半径
        self.customImageView.layer.shadowColor = [UIColor blackColor].CGColor; // 设置阴影的颜色为黑色
        self.customImageView.layer.shadowOpacity = 0.3; // 设置阴影的不透明度
        
        self.customImageView.image = [self createNonInterpolatedUIImageFormCIImage:ciImage size: 500];
    }
    

    2.生成高清二维码方法

    - (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)ciImage size:(CGFloat)widthAndHeight
    {
        CGRect extentRect = CGRectIntegral(ciImage.extent);
        CGFloat scale = MIN(widthAndHeight / CGRectGetWidth(extentRect), widthAndHeight / CGRectGetHeight(extentRect));
        
        // 1.创建bitmap;
        size_t width = CGRectGetWidth(extentRect) * scale;
        size_t height = CGRectGetHeight(extentRect) * scale;
        CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
        CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    
        CIContext *context = [CIContext contextWithOptions:nil];
        
        CGImageRef bitmapImage = [context createCGImage:ciImage fromRect:extentRect];
        CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
        CGContextScaleCTM(bitmapRef, scale, scale);
        CGContextDrawImage(bitmapRef, extentRect, bitmapImage);
        
        // 保存bitmap到图片
        CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
        CGContextRelease(bitmapRef);
        CGImageRelease(bitmapImage);
        
        //return [UIImage imageWithCGImage:scaledImage]; // 黑白图片
        UIImage *newImage = [UIImage imageWithCGImage:scaledImage];
        return [self imageBlackToTransparent:newImage withRed:200.0f andGreen:70.0f andBlue:189.0f];
    }
    

    3.设置图片透明度

    void ProviderReleaseData (void *info, const void *data, size_t size){
        free((void*)data);
    }
    - (UIImage*)imageBlackToTransparent:(UIImage*)image withRed:(CGFloat)red andGreen:(CGFloat)green andBlue:(CGFloat)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, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
        // 遍历像素
        int pixelNum = imageWidth * imageHeight;
        uint32_t* pCurPtr = rgbImageBuf;
        for (int i = 0; i < pixelNum; i++, pCurPtr++){
            if ((*pCurPtr & 0xFFFFFF00) < 0x99999900)    // 将白色变成透明
            {
                // 改成下面的代码,会将图片转成想要的颜色
                uint8_t* ptr = (uint8_t*)pCurPtr;
                ptr[3] = red; //0~255
                ptr[2] = green;
                ptr[1] = blue;
            }
            else
            {
                uint8_t* ptr = (uint8_t*)pCurPtr;
                ptr[0] = 0;
            }
        }
        // 输出图片
        CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
        CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace,
                                            kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
                                            NULL, true, kCGRenderingIntentDefault);
        CGDataProviderRelease(dataProvider);
        UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
        // 清理空间
        CGImageRelease(imageRef);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
        return resultUIImage;
    }
    

    效果图

    demo.png test.png

    相关文章

      网友评论

      • 程序员学园:不错,可不可以再高些其它样式,比如像这里的彩色二维码一样 http://www.it399.com/qrcode.jsp
      • c14bcd40d557:你的代码写在ViewController里面吗?
        船长_:是的
      • 可儿家族:没一篇都是干活啊,我感觉我现在项目中遇到的问题都能在你文章中找到答案啊
      • 溪枫狼:你的代码不能像最后一张图那样设置阴影吧?我试了你的代码,仅仅是在view加了阴影,对吗?
        船长_:@溪枫狼 是都有实现上图两种效果
        溪枫狼:@船长_ 我以为你实现了后面的效果,试了好几次,因为我也想实现那种效果,但是没找到方法
        船长_:@溪枫狼 仅供参考
      • 超_iOS:void ProviderReleaseData (void *info, const void *data, size_t size){
        free((void*)data);
        }
        这个是C语言的方法么?有点看不懂
        超_iOS:@船长_ 言简意赅,可以
      • ZealPenK:我将代码粘贴到控制器里;
        把self.customImageView设成@property (nonatomic, strong) UIImageView *customImageView;
        然后 [self.view addSubview:self.customImageView];
        为啥没显示呢?
        船长_:@ZealPenK 代码自定义ImageView,或者用xib,或故事板

      本文标题:iOS生成二维码(彩色 + 阴影)

      本文链接:https://www.haomeiwen.com/subject/rncyhttx.html