使用Swift生成具有透明背景的QR码

3

在我的Swift 2应用程序中,我可以像这样生成二维码:

let data = "1234567890".dataUsingEncoding(NSISOLatin1StringEncoding, allowLossyConversion: false)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter!.setValue(data, forKey: "inputMessage")
filter!.setValue("Q", forKey: "inputCorrectionLevel")
qrcodeImage = filter!.outputImage
let transformedImage = qrcodeImage.imageByApplyingTransform(CGAffineTransformMakeScale(150, 150))
QRCodeImage.image = UIImage(CIImage: transformedImage)

但是我的二维码得到了一个白色背景图像,但我想要一个透明的背景。 我尝试过类似这样的代码:
QRCodeImage.backgroundColor = UIColor.clearColor()

但是这并没有起作用。 有什么想法? :)

你可能需要在库中更改这个。 - Syed Ali Salman
我该怎么做?oO - Stack108
2
https://dev59.com/SWAf5IYBdhLWcg3w2Vso - Aruna Mudnoor
8个回答

6
似乎CIQRCodeGenerator滤镜总是使用黑白色。您可以将输出传递到CIMaskToAlpha过滤器以将其转换为透明。

首先,您可能想使用CIColorInvert来交换白色和黑色。


不错的挖掘 :) (点赞) - Syed Ali Salman
11
牛逼的家伙,但是你知道吗,一个小代码示例也不会有什么坏处! - jlstr

1

要想实现透明背景,你应该(运用直觉并)尝试这样做:

//Create a CIFalseColor Filter
let colorFilter: CIFilter = CIFilter(name: "CIFalseColor")!

colorFilter.setDefaults()

colorFilter.setValue(yourQRFilter.outputImage!, forKey: "inputImage")

//Then set the background colour like this,
let transparentBG: CIColor = CIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)

colorFilter.setValue(qrColor, forKey: "inputColor0")

colorFilter.setValue(transparentBG, forKey: "inputColor1")

outputImage = colorFilter.outputImage!

这应该会为您生成带有透明背景的QR码图像,我希望如此。

0
我认为关键在于背景的alpha通道上。您可以设置或者降低alpha值,减少或删除透明度。试试像这样的东西:
QRCodeImage.backgroundcolor = UIColor(white: 1, alpha: 0.5)

希望能有所帮助。


抱歉。@jtbandes的答案很好;另外,你在Arun Amayana引用的答案中可能会找到对你有用的代码:https://dev59.com/SWAf5IYBdhLWcg3w2Vso#24211683 - Xose Sanchez
问题是,这个解决方案不够快速 :( - Stack108
这个怎么样?QRCodeImage.backgroundColor = UIColor.clearColor() - Xose Sanchez
抱歉,再次道歉。也许这里有些不同:http://qiku.es/pregunta/264556/como-establecer-el-alfa-de-un-uiimage-en-swift-mediante-programacion-how-to-set-the-alpha-of-a-uiimage-in-swift-programmatically - Xose Sanchez

0

这是我的代码:

func QRImageFromData(_ data: Data) -> UIImage? {

    let filter = CIFilter(name: "CIQRCodeGenerator")
    filter?.setValue(data, forKey: "inputMessage")
    //filter?.setValue("H", forKey: "inputCorrectionLevel")

    //change qrcode color : #1e3259
    let filterFalseColor = CIFilter(name: "CIFalseColor")
    filterFalseColor?.setDefaults()
    filterFalseColor?.setValue(filter?.outputImage, forKey: "inputImage")
    // convert method
    let cgColor: CGColor? = UIColor(hex: "#1e3259")?.cgColor
    let qrColor: CIColor = CIColor(cgColor: cgColor!)
    let transparentBG: CIColor = CIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
    filterFalseColor?.setValue(qrColor, forKey: "inputColor0")
    filterFalseColor?.setValue(transparentBG, forKey: "inputColor1")


    if let image = filterFalseColor?.outputImage {
        let transform = CGAffineTransform(scaleX: 5.0, y: 5.0)
        return UIImage(ciImage: image.applying(transform),
            scale: 1.0,
            orientation: UIImageOrientation.up)
    } else {
        return nil
    }

}

0

除了@jtbandes的答案,我还写了一些代码,这样可以帮助其他人。

extension UIImage {

    func transparentBackground() -> UIImage? {
        let context = CIContext(options: nil)
        let filter = CIFilter(name: "CIMaskToAlpha")
        filter?.setDefaults()
        filter?.setValue(self.ciImage, forKey: kCIInputImageKey)
        if let output = filter?.outputImage,
           let imageRef = context.createCGImage(output, from: output.extent) {
            return UIImage(cgImage: imageRef)
        }
        return nil
    }

    func invertColor() -> UIImage? {
        let filter = CIFilter(name: "CIColorInvert")
        filter?.setDefaults()
        filter?.setValue(self.ciImage, forKey: kCIInputImageKey)
        if let output = filter?.outputImage {
            return UIImage(ciImage: output)
        }
        return nil
    }

}

并像这样使用它

yourUIImage.invertColor()?.transparentBackground()

transparentBackground()函数将移除黑色,留下白色;而invertColor()函数将交换黑白颜色。


0

我按照这个tutorial教程获得了一个带有透明背景的QR码。

添加这些扩展:

extension CIImage {
    /// Inverts the colors and creates a transparent image by converting the mask to alpha.
    /// Input image should be black and white.
    var transparent: CIImage? {
        return inverted?.blackTransparent
    }

    /// Inverts the colors.
    var inverted: CIImage? {
        guard let invertedColorFilter = CIFilter(name: "CIColorInvert") else { return nil }

        invertedColorFilter.setValue(self, forKey: "inputImage")
        return invertedColorFilter.outputImage
    }

    /// Converts all black to transparent.
    var blackTransparent: CIImage? {
        guard let blackTransparentFilter = CIFilter(name: "CIMaskToAlpha") else { return nil }
        blackTransparentFilter.setValue(self, forKey: "inputImage")
        return blackTransparentFilter.outputImage
    }

    /// Applies the given color as a tint color.
    func tinted(using color: UIColor) -> CIImage?
    {
        guard
            let transparentQRImage = transparent,
            let filter = CIFilter(name: "CIMultiplyCompositing"),
            let colorFilter = CIFilter(name: "CIConstantColorGenerator") else { return nil }

        let ciColor = CIColor(color: color)
        colorFilter.setValue(ciColor, forKey: kCIInputColorKey)
        let colorImage = colorFilter.outputImage

        filter.setValue(colorImage, forKey: kCIInputImageKey)
        filter.setValue(transparentQRImage, forKey: kCIInputBackgroundImageKey)

        return filter.outputImage!
    }
}


extension URL {

    func qrImage(using color: UIColor) -> UIImage? {
        let ciImage = qrCIImage?.tinted(using: color)
        return ciImage != nil ? UIImage(ciImage: ciImage!) : nil
    }

    var qrImage: UIImage? {
        return UIImage(ciImage: qrCIImage!)
    }

    /// Creates a QR code for the current URL in the given color.
    func qrCIImage(using color: UIColor) -> CIImage? {
        return qrCIImage?.tinted(using: color)
    }

    /// Returns a black and white QR code for this URL.
    var qrCIImage: CIImage? {
        guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
        let qrData = absoluteString.data(using: String.Encoding.ascii)
        qrFilter.setValue(qrData, forKey: "inputMessage")

        let qrTransform = CGAffineTransform(scaleX: 12, y: 12)
        return qrFilter.outputImage?.transformed(by: qrTransform)
    }

}

然后像这样使用:

let myChosenColor = UIColor(red:0.93, green:0.31, blue:0.23, alpha:1.00)
let qrURLImage = URL(string: "https://stackoverflow.com")?.qrImage(using: myChosenColor)
myQrImageView.image = qrURLImage

在 myQrImageView.image 中,您将看到一个带有透明背景的二维码图像:


0
extension UIImage {
    func alpha(_ value: CGFloat) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        draw(at: CGPoint.zero, blendMode: .normal, alpha: value)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

0

如果你正在寻找一个准备好的解决方案:

enum GeneratorType {
  case qrCode, barCode, aztecCode
  
  var filterName: String {
    switch self {
    case .aztecCode:
      return "CIAztecCodeGenerator"
    case .barCode:
      return "CICode128BarcodeGenerator"
    case .qrCode:
      return "CIQRCodeGenerator"
    }
  }
}

func generateCode(type: GeneratorType, text: String,
                  transform: CGAffineTransform = CGAffineTransform(scaleX: 32.0, y: 32.0),
                  fillColor: UIColor = UIColor.black,
                  backgroundColor: CIColor = CIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)) -> UIImage? {
  guard let filter = CIFilter(name: type.filterName) else {
    return nil
  }
  
  filter.setDefaults()
  
  guard let data = text.data(using: String.Encoding.utf8) else {
    return nil
  }
  
  filter.setValue(data, forKey: "inputMessage")
  
  let filterFalseColor = CIFilter(name: "CIFalseColor")
  filterFalseColor?.setDefaults()
  filterFalseColor?.setValue(filter.outputImage, forKey: "inputImage")
  filterFalseColor?.setValue(CIColor(cgColor: fillColor.cgColor), forKey: "inputColor0")
  filterFalseColor?.setValue(backgroundColor, forKey: "inputColor1")
  
  
  guard let image = filterFalseColor?.outputImage else { return nil }
  
  return UIImage(ciImage: image.transformed(by: transform), scale: 1.0,
                 orientation: UIImage.Orientation.up)
}

使用方法:

let qrImage = generateCode(type: .qrCode, text: "some text")

和平!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接