코어이미지를 사용한 QRCode 생성기

지난 시간에 코어 이미지를 사용해서 QRCode 인식기를 만드는 법에 대해서 간략히 설명하였는데, 그렇다면 반대로 문자열을 인코딩하여 QR코드를 만드는 것은 어떻게 할 수 있을까?
QR코드 생성은 코어 이미지를 통해서 할 수 있다. 코어이미지는 이미지 내의 바코드와 QR코드 탐지 API를 제공하는데, 반대로 해당 코드를 이미지로 생성하는 기능도 제공한다. QRCode 생성은 CIQRCodeGenerator 라는 이름의 CIFilter를 통해서 수행할 수 있다. 해당 필터의 파라미터는 다음과 같다.

  1. inputMessage : QR코드에 인코딩될 문자열 데이터이다. 해당 문자열은 UTF8로 인코딩된 바이트스트림으로 전달한다.
  2. inputCorrectionLevel : QR코드의 보정값 수준이다. 보통 “L” 을 쓰면 된다.

실제로 이미지를 만드는 방법은 다음과 같다.

let context = CIContext()
let message = "https://soooprmx.com"
if let data = message.data(using: .utf8),
   let filter = CIFilter(name: "CIQRCodeGenerator",
                         inputParameters:[
                            "inputMessage": data,
                            "inputCorrectionLevel": "L"])
{
  let qrCode = filter.outputImage()!
  let output = UIImage(ciImage: qrCode)
  ...
}

다만, 문제는 이렇게 생성된 이미지가 매우 크기가 작다는 문제이다. (정말 쥐똥만함….) 이 이미지를 보다 큰 이미지뷰에 넣으면 확대되면서 픽셀 보간1이 일어나서 이미지가 흐려지게 된다. (물론 적당히 크기가 크다면 이런 흐린 QR이미지도 왠만한 앱에 의해서는 다 인식된다.) 하지만 QR이미지를 파일로 저장하려고 하거나 하는 경우에는 흐릿한 이미지도, 너무 작은 이미지도 쓸 수가 없으므로 다음과 같이 확대하자. 코어 그래픽을 사용해서 픽셀 보간 없이 큰 영역에 해당 이미지를 그려주면 된다.

...
let qrCode = filter.outputImage()!
let cgImg = context.createCGImage(qrCode, from: cqCode.extent)!
// 비트맵 컨텍스트를 생성한다.
let v_size: Int = 400
guard let ctx = CGContext(data:nil, width: v_size, height: v_size,
                    bitsPerComponent:8, bytesPerRow:0,
                    space: CGColorSpaceCreateDeviceRGB(),
                    bitmapInfo: CGImageAlphaInfo.none.rawValue)
else {
   return
}
let outputFrame = CGRect(x:0, y:0, width: CGFloat(v_size), height: CGFloat(v_size))
// 보간 옵션을 제외한 후, QR코드를 확대하여 그린다.
ctx.interpolationQuality = .none
ctx.draw(cgImg, in: outputFrame)
// 최종적으로 확대된 결과물
let resultImage = ctx.makeImage()!
let qrCodeImage = UIImage(cgImage: resultImage)

  1. 흔히 ‘안티앨리어싱’이라 부르는 그것. 

Read more

워드프레스에서 고스트로 이전

워드프레스에서 고스트로 이전

이 글을 쓰면서도 믿기 힘든 사실인데, 블로그라는 걸 처음 시작한지가 20년이 되었습니다. 이글루스에서 처음 시작했다가, SK컴즈가 인수한다고 발표함과 동시에 워드프레스로 플랫폼을 옮겼죠. 워드프레스오 옮긴 이후에는 호스팅 환경을 이리 저리 옮기긴 했지만 거의 18년 가까이 워드프레스를 사용해온 것 같습니다. 그 동안 워드프레스는 블로깅 툴에서 명실상부한 범용CMS로 발전했습니다. 사실 웬만한 홈페이지들은 이제

By sooop
띄어쓰기에 대한 생각

띄어쓰기에 대한 생각

업무 메일을 쓸 때 가장 많이 쓰는 말 중에 하나가 메일 말미에 ‘업무에 참고 부탁 드립니다.‘인데요, 어느 날부터 아웃룩에서 이 ‘부탁 드립니다’가 틀렸다고 맞춤법 지적을 하기 시작했습니다. 맞는 말은 ‘부탁드립니다’라고 붙여 쓰는 거라고. 사실 아래아한글 시절부터 이전의 MS워드까지, 워드프로세서들의 한국어 맞춤법 검사 실력은 거의 있으나 마나 한

By sooop

구글 포토에서 아이클라우드로 탈출한 후기

한 때 구글 포토가 백업 용량을 무제한으로 제공해 주겠다고해서, 구글 포토를 사용해서 사진을 백업해왔습니다. 물론 이 이야기의 결말은 저나 이 글을 읽고 있는 여러분이나 모두 알고 있습니다. 사실 AI에게 학습 시킬 이미지 데이터를 모으기 위한 것일 뿐이라거나 하는 이야기는 그 당시에도 있었습니다만, 에이 그래도 구글인데 용량은 넉넉하게 주겠지…하는 순진한

By sooop

Julia의 함수 사용팁

연산자의 함수적 표기 Julia의 연산자는 기본적으로 함수이며, 함수 호출 표기와 같은 방식으로 호출하는 것이 가능합니다. 또한 그 자체로 함수이기 때문에 filter(), map() 과 같이 함수를 인자로 받는 함수에도 연산자를 그대로 적용하는 것이 가능합니다. 특히 + 연산자는 sum() 함수와 같이 여러 인자를 받아 인자들의 합을 구할 수 있습니다. 2 + 3 # = 5 +(2,

By sooop