2015-12-27 6 views
1

У меня возникла проблема с использованием CIQRCodeGenerator, чтобы создать QR-код: когда я сначала генерирую код, он четкий, но когда я снова запускаю функцию с тем же вводом, QR-код становится размытым :CIQRCodeGenerator Предоставление несогласованных результатов

Initial Run (более понятно):

initial function run

Второй Run (более размыто):

second function run

Следующая функция сначала вызывается в viewWillAppear и затем запускается после нажатия пользователем кнопки.

func generateQRCodeFromString(string: String) -> UIImage? { 
    let data = string.dataUsingEncoding(NSISOLatin1StringEncoding) 

    if let filter = CIFilter(name: "CIQRCodeGenerator") { 
     filter.setValue(data, forKey: "inputMessage") 
     filter.setValue("H", forKey: "inputCorrectionLevel") 
     let transform = CGAffineTransformMakeScale(10, 10) 

     if let output = filter.outputImage?.imageByApplyingTransform(transform) { 
      return UIImage(CIImage: output) 
     } 
    } 

    return nil 
} 

Образца проект, иллюстрирующий проблему можно посмотреть здесь: http://jakeserver.com/Uploads/Apps/QR_Test.zip

Есть ли причина, почему UIImage становится расплывчатой ​​после того, как функция выполняется второй раз с тем же входом?

EDIT - Добавлена ​​дополнительная информация

override func viewDidLoad() { 
    super.viewDidLoad() 
    qrCode.image = generateQRCodeFromString("test", size: qrCode.frame.size); 
} 

override func viewWillLayoutSubviews() { 
    qrCodeWidth.constant = self.view.frame.width * 0.8; 
} 
@IBAction func buttonTapped(sender: AnyObject) { 
    qrCode.image = generateQRCodeFromString("test", size: qrCode.frame.size); 
} 
+0

В 'viewDidLoad'' qrCode.frame.size', вероятно, неправильный размер. Может быть, переместить это в 'viewDidLayoutSubviews'? Кроме того, я думаю, вы должны называть 'super' в' viewWillLayoutSubviews'. –

+0

@AaronBrager Спасибо за вашу помощь. Я думаю, что перемещение вызова в метод didLayout исправил его в этом экземпляре. У меня был еще один быстрый вопрос: можно ли сделать его более резким, чем в настоящее время? Даже со шкалой 2, она по-прежнему выглядит немного расплывчатой. –

+0

@AaronBrager Я понял ответ на мой вопрос о последующей работе, мне пришлось удвоить значения ширины и высоты в линии шкалы. Еще раз спасибо за вашу помощь. –

ответ

1

Я не уверен, почему изменения размытость между прогонов (возможно, внутренняя деталь реализации), но в коде Objective-C Я работал вокруг этого, делая QR-код, а затем вручную записывать изображение в контекст растрового изображения большего размера.

я принял удар на портирование этого кода Swift и придумал это:

func generateQRCodeFromString(string: String, size: CGSize) -> UIImage? { 
    guard let data = string.dataUsingEncoding(NSISOLatin1StringEncoding), 
     let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil } 

    filter.setDefaults() 
    filter.setValue(data, forKey: "inputMessage") 
    filter.setValue("H", forKey: "inputCorrectionLevel") 

    guard let image = filter.outputImage else { return nil } 

    let extent = CGRectIntegral(image.extent) 
    let scale = min(size.width/extent.width, size.height/extent.height); 

    let (height, width) = (extent.height * scale, extent.width * scale) 
    let colorSpace = CGColorSpaceCreateDeviceGray() 
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.None.rawValue) 

    guard let bitmapContext = CGBitmapContextCreate(nil, Int(width), Int(height), 8, 0, colorSpace, bitmapInfo.rawValue) else { return nil } 

    CGContextSetInterpolationQuality(bitmapContext, CGInterpolationQuality.None) 
    CGContextScaleCTM(bitmapContext, CGFloat(scale), CGFloat(scale)) 
    CGContextDrawImage(bitmapContext, extent, CIContext().createCGImage(image, fromRect: extent)) 

    if let scaledImage = CGBitmapContextCreateImage(bitmapContext) { 
     return UIImage(CGImage: scaledImage) 
//  You might need to use this instead: 
//  return UIImage(CGImage: <#T##CGImage#>, scale: <#T##CGFloat#>, orientation: <#T##UIImageOrientation#>) 

    } 

    return nil 
} 

Будет ли это работать для вашего случая использования?

Кстати, я не думаю, что это вызвало проблему, но вы не разворачивая data (dataUsingEncoding(_:) возвращает NSData? не NSData).

+0

Я также не уверен, что 'CGImageAlphaInfo.None',' CGImageAlphaInfo.NoneSkipFirst' или 'CGImageAlphaInfo.NoneSkipLast' будет быть наиболее уместным здесь. –

+0

Благодарим вас за ответ. Теперь кажется, что возникает обратная проблема: изображение начинает размываться, а затем становится четким при нажатии кнопки. Любые идеи, почему это может произойти? –

+0

@JakeChasan Ни в коем случае не с головы. Возможно, это связано с настройкой контроллера просмотра/просмотра, а не с реализацией 'CIFilter'? Можете ли вы опубликовать свой код «viewWillAppear» и кнопку «Ключ от кнопки»? –

Смежные вопросы