4

Here are the codes:

@interface InterfaceController()
@property (nonatomic, weak) IBOutlet WKInterfaceImage *qrImage;
@property (nonatomic, weak) IBOutlet WKInterfaceLabel *label;
@end

@implementation InterfaceController
- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    [self.label setText: @"Welcome"];
    UIImage *image = [InterfaceController generateQRCodeWithString:@"Welcome"];
    [self.qrImage setImage:image];
}

- (void)willActivate {
    [super willActivate];
}

- (void)didDeactivate {
    [super didDeactivate];
}

+ (UIImage *)generateQRCodeWithString:(NSString *)string {
    NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    [filter setValue:stringData forKey:@"inputMessage"];
    [filter setValue:@"M" forKey:@"inputCorrectionLevel"];

    CIImage *input = filter.outputImage;
    CGAffineTransform transform = CGAffineTransformMakeScale(10.0f, 10.0f);
    CIImage *output = [input imageByApplyingTransform: transform];

    return [UIImage imageWithCIImage:output];
}
@end

I'm trying to generate a QR code from some specific text and show it in the watch interface. The problem is that the UIImage generated by generateQRCodeWithString: is never shown. However, if I load an image with [UIImage imageNamed:@"XXX.png"] from the WatchKit Extension bundle, it's shown properly.

I'm not sure what's going on. What did I miss? Thanks in advance.


UPDATE: In response to msk, yes I'm pretty sure. I tried to NSLog the image, it gives <UIImage: 0x7fc261d276e0>, {230, 230}

Jinghan Wang
  • 1,139
  • 12
  • 21
  • Can you confirm that generateQRCodeWithString is returning an image (not nil)? – msk Mar 08 '15 at 17:07
  • This code should be correct. I've been pulling my hair out trying to figure this one out (for days)!! It's obvious that your image is not nil, yet it is somehow deallocated or deleted when you go to set it in a `WKInterfaceImage`. My best guess is that it's a bug with `WKInterfaceImage`. – Sam Spencer Mar 08 '15 at 18:55
  • 1
    You kinda gave me hope when I saw you generating QRCodes in the watch. It seems that WatchOS2 doesn't support this :( – Tiago Almeida Feb 08 '16 at 14:30
  • Would you explain, please? How can you use Core Image with WatchKit? – CFIFok Dec 21 '17 at 08:04

1 Answers1

2

The image returned from generateQRCodeWithString: isn't a "real" image (to be brief) and hasn't been fully rendered out. Think of the CIImage as a concept of what the image should look like rather than actual pixels.

Replace the return line in generateQRCodeWithString: with something like this:

CGImageRef cgOutput = [[CIContext contextWithOptions:nil]
                       createCGImage:output fromRect:output.extent];
return [UIImage imageWithCGImage:cgOutput];

That will render the QR code to a CGImage to turn it into pixels, and then on to a UIImage.

Creating the CIContext is relatively expensive and if you're generating a lot of QR codes, the context should be static or something and initialized once. But for a one-off, it should be fine.

gregheo
  • 4,182
  • 2
  • 23
  • 22