iOS 7 Core Image QR Code generation too blur

前端 未结 8 1485
心在旅途
心在旅途 2020-12-24 02:44

here\'s my code for generating QRCode image

+ (UIImage *)generateQRCodeWithString:(NSString *)string {
    NSData *stringData = [string dataUsingEncoding:NSU         


        
相关标签:
8条回答
  • 2020-12-24 03:01

    Rewrite @Benoît Caron's answer in Swift 3.1:

    func convertTextToQRCode(text: String, withSize size: CGSize) -> UIImage {
    
        let data = text.data(using: String.Encoding.isoLatin1, allowLossyConversion: false)
    
        let filter = CIFilter(name: "CIQRCodeGenerator")!
    
        filter.setValue(data, forKey: "inputMessage")
        filter.setValue("L", forKey: "inputCorrectionLevel")
    
        let qrcodeCIImage = filter.outputImage!
    
        let cgImage = CIContext(options:nil).createCGImage(qrcodeCIImage, from: qrcodeCIImage.extent)
        UIGraphicsBeginImageContext(CGSize(width: size.width * UIScreen.main.scale, height:size.height * UIScreen.main.scale))
        let context = UIGraphicsGetCurrentContext()
        context!.interpolationQuality = .none
    
        context?.draw(cgImage!, in: CGRect(x: 0.0,y: 0.0,width: context!.boundingBoxOfClipPath.width,height: context!.boundingBoxOfClipPath.height))
    
        let preImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    
        let qrCodeImage = UIImage(cgImage: (preImage?.cgImage!)!, scale: 1.0/UIScreen.main.scale, orientation: .downMirrored)
    
        return qrCodeImage
    }
    
    0 讨论(0)
  • 2020-12-24 03:04

    To fix the blur looks in QR code generated by using CIFilter: The basic idea for scaling-up the QR code image without making it blurry, is to change its transform property. But, as it’s infeasible to scale up the image and add it at the same time to the image view, we’ll just create another CIImage which will be scaled-up and then we’ll assign it to the image view.

    Objective C:

    - (void)createQRForData:(id)qrData forImageView:(UIImageView *)imageView {
    
        NSData *data = [NSJSONSerialization dataWithJSONObject:qrData options:NSJSONWritingPrettyPrinted error:nil];
    
        CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
        [qrFilter setValue:data forKey:@"inputMessage"];
        [qrFilter setValue:@"Q" forKey: @"inputCorrectionLevel"];
    
        //Scaling the CIFilter image as per the UIImageView frame. 
        CGFloat scaleX = imageView.frame.size.width / qrFilter.outputImage.extent.size.width;
        CGFloat scaleY = imageView.frame.size.height / qrFilter.outputImage.extent.size.height;
        CIImage *transformedImage = [qrFilter.outputImage imageByApplyingTransform:CGAffineTransformMakeScale(scaleX, scaleY)];
    
        UIImage *QRImage = [UIImage imageWithCIImage:transformedImage];
    
        imageView.image = QRImage;
    }
    

    This helped me to resolve the blurry looks in QR code.

    0 讨论(0)
  • 2020-12-24 03:05

    Maybe you should try this. Here is a swift tutotial.

    + (UIImage *)generateQRCodeImageBySize:(CGFloat)size andString:(NSString *)string {
    
        CIImage *qrCodeImage = [[CIImage alloc] init];
    
        NSData *stringData = [string dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:NO];
    
        CIFilter *ciFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
        [ciFilter setValue:stringData forKey:@"inputMessage"];
        [ciFilter setValue:@"Q" forKey:@"inputCorrectionLevel"];
    
        qrCodeImage = ciFilter.outputImage;
    
        CGFloat scaleX = size / qrCodeImage.extent.size.width;
        CGFloat scaleY = size / qrCodeImage.extent.size.height;
        CIImage *transformedQRImage = [qrCodeImage imageByApplyingTransform:CGAffineTransformMakeScale(scaleX, scaleY)];
    
        return [UIImage imageWithCIImage:transformedQRImage];
    }
    
    0 讨论(0)
  • 2020-12-24 03:09

    I was about to start bounty on this question but i found the answer.

    What you need is a scale filter. To achieve this with CoreImage, you need to do something like this:

    CIImage *input = [CIImage imageWithCGImage: ImageView.Image.CGImage]; // input image is 100 X 100
    CGAffineTransform transform = CGAffineTransformMakeScale(5.0f, 5.0f); // Scale by 5 times along both dimensions
    CIImage *output = [input imageByApplyingTransform: transform];
    // output image is now 500 X 500
    

    FROM THIS SO ANSWER: https://stackoverflow.com/a/16316701/2859764

    0 讨论(0)
  • 2020-12-24 03:14

    This method will use CoreImage to generate the QR code as a CIImage. Unfortunately, there's no simple way to disable interpolation, so scaling the image will create a blurry code. The workaround is to create temporary CGImageRef with the bits and draw it into a grayscale bitmap CGContextRef.

    Tested on OSX but should work on iOS as written.

    - (CGImageRef)createQRImageForString:(NSString *)string size:(CGSize)size {
      // Setup the QR filter with our string
      CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
      [filter setDefaults];
    
      NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
      [filter setValue:data forKey:@"inputMessage"];
      CIImage *image = [filter valueForKey:@"outputImage"];
    
      // Calculate the size of the generated image and the scale for the desired image size
      CGRect extent = CGRectIntegral(image.extent);
      CGFloat scale = MIN(size.width / CGRectGetWidth(extent), size.height / CGRectGetHeight(extent));
    
      // Since CoreImage nicely interpolates, we need to create a bitmap image that we'll draw into
      // a bitmap context at the desired size;
      size_t width = CGRectGetWidth(extent) * scale;
      size_t height = CGRectGetHeight(extent) * scale;
      CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
      CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    
    #if TARGET_OS_IPHONE
      CIContext *context = [CIContext contextWithOptions:nil];
    #else
      CIContext *context = [CIContext contextWithCGContext:bitmapRef options:nil];
    #endif
    
      CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
    
      CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
      CGContextScaleCTM(bitmapRef, scale, scale);
      CGContextDrawImage(bitmapRef, extent, bitmapImage);
    
      // Create an image with the contents of our bitmap
      CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    
      // Cleanup
      CGContextRelease(bitmapRef);
      CGImageRelease(bitmapImage);
    
      return scaledImage;
    }
    
    0 讨论(0)
  • 2020-12-24 03:20

    Easiest solution is to add following to your image view:

    imgViewQR.layer.magnificationFilter = kCAFilterNearest
    

    This will automatically upscale your generated QR code image to imageview's size using nearest which results in sharp, pixelated image. This usually isn't what you want when resizing icons/photos but is perfect for QR codes

    (it doesn't seem to work on simulator but works great on real device

    0 讨论(0)
提交回复
热议问题