I've been writing about (and using) QR codes for a couple of decades. I love the innovation that happens within the bounds of the specification.
One problem that I foresee with this is that they don't look like QR codes. People are now used to looking for a specific monochrome pattern to point their phone towards.
There was a competitor to QR - MS Tag - which tried something similar. Their codes were able to be integrated into designs without the "ugliness" of QR codes. The problem is, no one knew they were there!
The corner targets are still visible in Nitro's codes - so hopefully people will spot them. But I think it is OK to embrace the ugly. Not everything needs to be smothered in your corporate branding. Something which is standardised across multiple things is useful.
The irony is you can scan a URL with a phone camera and it's clickable, with the nice side-effect that the domain is human-inspectable. Just make the font a little bigger and it scans easily.
QR codes are fascinating though, as they can encode more than mere URLs. But the vast majority in the consumer space are links. For that purpose, I'm rooting for OCR.
Agree with a lot here.
QR Codes have however become a cornerstone of digital convenience in a lot of the world. All the more true here in India, where basically everything is using QR Codes, from payments to restaurant menus.
People here are still not used to using Lens + OCR.
Then, there are issues like long links or confusing zeroes and O's.
QR Codes solve these pretty well, I believe.
it’s gotten to the point where I’ll find myself screenshotting text and using ocr to grab links because sometimes apps disable highlighting text for whatever reason.
A big advantage of QR code is that it's just a square, whereas URLs occupy short, wide rectangles of space. They are also robust to a number of situations where OCR may struggle: small size, low light, fading...
And they are human-inspectable. It is regrettable that iOS's camera app just prompts you to open a QR-encoded URL in a Web browser, but you can use a "passive" scanner that just reveals the payload without risk.
The classic Russ Cox QArt code doesn't suffer from this. [0]
There is Russ Cox's QArt coder [1] that does actually make the code match an image by manipulating the padding (it works by adding a #<padding> on the end).
That is a fair bit closer to 'intelligently merged with the QR code's essential data'.
I wrote a blog post about QR codes with an overview of image techniques like this and a bunch of links to different implementations if anyone would like to see more things like this.
Ohh, the good old AI generated ones. I loved them when they came out. They look really good.
Each has their own merits though, in my opinion.
It's more expensive at scale to generate those. The results are also non-dererministic meaning the output can vary wildly while keeping the Qar information intact through Controlnet, which is not the case with our approach. The AI generated QRs also often don't really look like actual QR Codes, until you pull a scanner out. This is why I'm not really considering adding anymore customisation to this tool. Gives it a unique visual identity.
[deleted]
Hi! These look fancy but there are obviously issues around scanability. At first glance, you can probably make them readable with libraries like ZXing and others by keeping the finder patterns intact, i.e. making sure there is always a bit of white space (ISO mandates a 1-module width white border) around them.
So, no custom scanners are really needed. But there are of course issues with scannability that become worse the longer the payload is. Easily solvable with link shortening though.
The robustness centers around how modern scanners really work. No scanners really matching data module by data module. They're sampling the centroids in the approximate locations. So long as we keep the relevant centroids the right color, we can use the rest of the space as we want. There is more that can potentially be customized too, but I like how it currently looks. Might add rounded borders though.
The examples look a lot better than what I'm seeing in my own attempts and on the "Wall of QRs", I wonder if it's just because we're not using "High Res" or if there's some fine-tuning of the source-image involved.
In any case, this is massively cool. Did you see that little egg fella? He's got sunglasses and everything.
This is cool, but what's the use of error correction when you're deliberately introducing noise?
In my experience, these art-y qr codes are more challenging to scan than traditional plain variants, especially in real life scenarios where you don't always have a perfectly clear image
Modern iOS and Samsung devices have very good QR code libraries which work well even under challenging conditions. Other Android manufacturers (e.g. Xiaomi) and a lot of the "QR Scanner" apps on Google Play use a really old library that doesn't work well under perfect conditions.
The error correction is actually what enables the artistic elements - QR codes with high EC levels (H=30%) can have up to 30% of their modules modified while remaining scannable, which is exactly what these image-embedding techniques exploit.
The point of the error correction is to allow QR codes to work despite wear and tear - dirt, fading, poor lighting, etc. If you "use up" the margin of allowed errors just to make it pretty, it's not going to work as well in less-than-ideal circumstances.
Agreed that these might not work flawlessly on T-Shirts for example.
Does work on flat surfaces in my experience, but yes, there's a slight tradeoff.
Hei ! Just wanted to drop by to say that i tested this with a black and white logo that I had generated ; sounded like the worst case scenario ; it handled it flawlessly ; the picture didn't look the best - but the job was done and it worked. Bookmarked it will definitely use it if i need to !
Is this a commercial project or an open-source ?
It's a commercial project but I'm of course not planning to monetize the QR generation. That'll always remain free.
Currently adding more features that would appeal more to enterprises or businesses. Those will be the only paid features
This looks great!
I also gave it a try, uploaded a transparent png (which was converted to black, fair enough, guess there's no good default choice for all cases) and scanned the pretty QR code with my phone: Flawless.
Thanks for building and sharing this, I love to see QR codes become more readable
There is a toggle to preserve color. Give it a shot!
I wonder how well these scan under less-than-ideal lighting and focus conditions. The standard QR code would be a lot more robust...
It's a slight tradeoff. Digital works flawlessly though
Still experimenting with how it works with print.
Digital is trivial. what you want is to be able to scan a QR code off a person's shirt, on a photograph taken at a convention, from a distance.
Yep, found those really interesting when they came out. I used to run an AI startup until a short while ago. In my opinion, the cost to utility ratio still isn't there for most use cases.
So, that's why I wanted to find something deterministic, without all the compute consumption.
NitroQRs generate the same as normal QRs with some good old computing, and can be generated in bulk for basically nothing.
"This halftone pattern is then intelligently merged with the QR code's essential data."
You cannot intelligently merge anything with the data. Otherwise it would change the data. The data is firmly packed on the rightmost side of the code (in the usual orientation). There is no space to weave anything in there. The only way to have anywhere to weave anything in is to choose an oversized code, and then manipulate the padding in the free space after the data, if you go only slightly out of spec (it's supposed to be a specific pattern, but any qr code reader I found doesn't give a damn about what's after the data).
"We leverage the highest level of error correction (Level H), which allows up to 30% of the data to be "damaged" or altered while remaining perfectly scannable. By using this capacity for the image pattern, we create a code that is both visually striking and reliable."
This is a completely nonsensical statement. You can manipulate the padding, to get some control over the generated reed solomon blocks (using the fact that RS encoded data is closed under XOR), although you won't be able to fully control all of those bits. But you can fully control the padding bits. So what you want is to have more padding, and less error correction, so you have maximum control. In which case, using the highest error correction level is hugely detrimental to the aim of making a QR code contain a picture. You cannot use the "30% error correcting capacity" to store the image. Those bits depend solely on the data and padding. The only control you have is over the padding (although you can get some indirect control over some ECC bits, if you give up control of several padding bits).
As for the reliability claim: I tried scanning the codes on the top image of the article with 10 codes on it. I first tried https://zxing.org/w/decode.jspx and it identified exactly none of them. I then tried with an application called BinaryEye on android, and it managed to scan 3 of them, but failed to recognize 7 of them. Enough said.
What they did was shrink each module to allow some of the background to bleed through. Which also makes their other claim that they do some halftoning thing quite irrelevant, you can have any color palette you want in the background (even full-on rgb). They are NOT part of the QR code, you just have to ensure the overall contrast of the module is distinguishable between the two states, conveniently achieved by the "ugly" black and white boxes dotted around the code. What this does is only make the code partially readable, because the scanner has a hard time interpreting a lot of the modules, and relies on error correction to recover the damaged parts.
They are not making the image into a QR code. Not a valid one anyway. They claim the code itself becomes the image, but it's really just a different way of partially damaging a valid QR code (spread the error over the whole area, instead of concentrating it in the middle). If it were a valid QR code, then a perfect picture of one (directly out of the generator, not taken from a photo, so it's as clean and perfect as can be) would be scanned correctly (most didn't) and it also does so with ZERO errors on any of the reed solomon blocks in the code. This project achieves nothing particularly interesting.
I've been writing about (and using) QR codes for a couple of decades. I love the innovation that happens within the bounds of the specification.
One problem that I foresee with this is that they don't look like QR codes. People are now used to looking for a specific monochrome pattern to point their phone towards.
There was a competitor to QR - MS Tag - which tried something similar. Their codes were able to be integrated into designs without the "ugliness" of QR codes. The problem is, no one knew they were there!
See https://shkspr.mobi/blog/2010/11/ms-tags-vs-qr-codes/#not-as...
The corner targets are still visible in Nitro's codes - so hopefully people will spot them. But I think it is OK to embrace the ugly. Not everything needs to be smothered in your corporate branding. Something which is standardised across multiple things is useful.
The irony is you can scan a URL with a phone camera and it's clickable, with the nice side-effect that the domain is human-inspectable. Just make the font a little bigger and it scans easily.
QR codes are fascinating though, as they can encode more than mere URLs. But the vast majority in the consumer space are links. For that purpose, I'm rooting for OCR.
Agree with a lot here. QR Codes have however become a cornerstone of digital convenience in a lot of the world. All the more true here in India, where basically everything is using QR Codes, from payments to restaurant menus. People here are still not used to using Lens + OCR. Then, there are issues like long links or confusing zeroes and O's. QR Codes solve these pretty well, I believe.
it’s gotten to the point where I’ll find myself screenshotting text and using ocr to grab links because sometimes apps disable highlighting text for whatever reason.
A big advantage of QR code is that it's just a square, whereas URLs occupy short, wide rectangles of space. They are also robust to a number of situations where OCR may struggle: small size, low light, fading...
And they are human-inspectable. It is regrettable that iOS's camera app just prompts you to open a QR-encoded URL in a Web browser, but you can use a "passive" scanner that just reveals the payload without risk.
The classic Russ Cox QArt code doesn't suffer from this. [0]
[0] https://research.swtch.com/qart
The innovation here mostly seems to be shrinking the QR code dots and putting them over a background image? Frankly, these look pretty terrible.
There's ones that look really bad, and others that look like they were just supposed to be. Here's one of my favourites: https://x.com/bhasinanant/status/1956313568665571431
Over on Mastodon we've just recently been having some fun with these techniques:
Dithering: https://mathstodon.xyz/@andrewt/115035614385265413
Mondrian: https://mathstodon.xyz/@OscarCunningham/115049490241833844
Hand Drawn: https://mathstodon.xyz/@andrewt/115056697540191327
Bad Apple: https://pony.social/@luna/115057532794342459
White Noise: https://pony.social/@luna/115058126613306302
That mondrian one is super neat!
You should check these out; they're amazing.
These are really creative!
There is Russ Cox's QArt coder [1] that does actually make the code match an image by manipulating the padding (it works by adding a #<padding> on the end). That is a fair bit closer to 'intelligently merged with the QR code's essential data'.
[1]: https://research.swtch.com/qr/draw/
I wrote a blog post about QR codes with an overview of image techniques like this and a bunch of links to different implementations if anyone would like to see more things like this.
https://kylezhe.ng/posts/crafting_qr_codes#image-techniques links directly to that section and skips the fluff about how QR codes work
I highly recommend checking out https://cgv.cs.nthu.edu.tw/projects/Recreational_Graphics/MQ... which uses word clouds with QR codes and looks crazy cool
Prior art: https://research.swtch.com/qart https://research.swtch.com/field
To be honest i found this approach superior
https://arstechnica.com/information-technology/2023/09/dream...
Ohh, the good old AI generated ones. I loved them when they came out. They look really good. Each has their own merits though, in my opinion. It's more expensive at scale to generate those. The results are also non-dererministic meaning the output can vary wildly while keeping the Qar information intact through Controlnet, which is not the case with our approach. The AI generated QRs also often don't really look like actual QR Codes, until you pull a scanner out. This is why I'm not really considering adding anymore customisation to this tool. Gives it a unique visual identity.
Hi! These look fancy but there are obviously issues around scanability. At first glance, you can probably make them readable with libraries like ZXing and others by keeping the finder patterns intact, i.e. making sure there is always a bit of white space (ISO mandates a 1-module width white border) around them.
So, no custom scanners are really needed. But there are of course issues with scannability that become worse the longer the payload is. Easily solvable with link shortening though. The robustness centers around how modern scanners really work. No scanners really matching data module by data module. They're sampling the centroids in the approximate locations. So long as we keep the relevant centroids the right color, we can use the rest of the space as we want. There is more that can potentially be customized too, but I like how it currently looks. Might add rounded borders though.
The examples look a lot better than what I'm seeing in my own attempts and on the "Wall of QRs", I wonder if it's just because we're not using "High Res" or if there's some fine-tuning of the source-image involved.
In any case, this is massively cool. Did you see that little egg fella? He's got sunglasses and everything.
One of my absolute favourites. Here's a thread of some other great ones: https://x.com/bhasinanant/status/1956313568665571431 High-res helps the quality too, though.
This is cool, but what's the use of error correction when you're deliberately introducing noise?
In my experience, these art-y qr codes are more challenging to scan than traditional plain variants, especially in real life scenarios where you don't always have a perfectly clear image
Modern iOS and Samsung devices have very good QR code libraries which work well even under challenging conditions. Other Android manufacturers (e.g. Xiaomi) and a lot of the "QR Scanner" apps on Google Play use a really old library that doesn't work well under perfect conditions.
The error correction is actually what enables the artistic elements - QR codes with high EC levels (H=30%) can have up to 30% of their modules modified while remaining scannable, which is exactly what these image-embedding techniques exploit.
The point of the error correction is to allow QR codes to work despite wear and tear - dirt, fading, poor lighting, etc. If you "use up" the margin of allowed errors just to make it pretty, it's not going to work as well in less-than-ideal circumstances.
Agreed that these might not work flawlessly on T-Shirts for example. Does work on flat surfaces in my experience, but yes, there's a slight tradeoff.
Hei ! Just wanted to drop by to say that i tested this with a black and white logo that I had generated ; sounded like the worst case scenario ; it handled it flawlessly ; the picture didn't look the best - but the job was done and it worked. Bookmarked it will definitely use it if i need to !
Is this a commercial project or an open-source ?
It's a commercial project but I'm of course not planning to monetize the QR generation. That'll always remain free. Currently adding more features that would appeal more to enterprises or businesses. Those will be the only paid features
Reminds me of perforated LSD sheets (https://d2cbg94ubxgsnp.cloudfront.net/Pictures/2000xAny/9/1/...)
This looks great! I also gave it a try, uploaded a transparent png (which was converted to black, fair enough, guess there's no good default choice for all cases) and scanned the pretty QR code with my phone: Flawless. Thanks for building and sharing this, I love to see QR codes become more readable
There is a toggle to preserve color. Give it a shot!
I wonder how well these scan under less-than-ideal lighting and focus conditions. The standard QR code would be a lot more robust...
It's a slight tradeoff. Digital works flawlessly though Still experimenting with how it works with print.
Digital is trivial. what you want is to be able to scan a QR code off a person's shirt, on a photograph taken at a convention, from a distance.
Title reminded me of these https://mp.weixin.qq.com/s/i4WR5ULH1ZZYl8Watf3EPw
Yep, Stable Diffusion & ControlNet can make for great QR codes. There are even a few dedicated models for it https://qrdiffusion.com/blog/controlnet-models-for-qr-codes
Yep, found those really interesting when they came out. I used to run an AI startup until a short while ago. In my opinion, the cost to utility ratio still isn't there for most use cases. So, that's why I wanted to find something deterministic, without all the compute consumption. NitroQRs generate the same as normal QRs with some good old computing, and can be generated in bulk for basically nothing.
"This halftone pattern is then intelligently merged with the QR code's essential data."
You cannot intelligently merge anything with the data. Otherwise it would change the data. The data is firmly packed on the rightmost side of the code (in the usual orientation). There is no space to weave anything in there. The only way to have anywhere to weave anything in is to choose an oversized code, and then manipulate the padding in the free space after the data, if you go only slightly out of spec (it's supposed to be a specific pattern, but any qr code reader I found doesn't give a damn about what's after the data).
"We leverage the highest level of error correction (Level H), which allows up to 30% of the data to be "damaged" or altered while remaining perfectly scannable. By using this capacity for the image pattern, we create a code that is both visually striking and reliable."
This is a completely nonsensical statement. You can manipulate the padding, to get some control over the generated reed solomon blocks (using the fact that RS encoded data is closed under XOR), although you won't be able to fully control all of those bits. But you can fully control the padding bits. So what you want is to have more padding, and less error correction, so you have maximum control. In which case, using the highest error correction level is hugely detrimental to the aim of making a QR code contain a picture. You cannot use the "30% error correcting capacity" to store the image. Those bits depend solely on the data and padding. The only control you have is over the padding (although you can get some indirect control over some ECC bits, if you give up control of several padding bits).
As for the reliability claim: I tried scanning the codes on the top image of the article with 10 codes on it. I first tried https://zxing.org/w/decode.jspx and it identified exactly none of them. I then tried with an application called BinaryEye on android, and it managed to scan 3 of them, but failed to recognize 7 of them. Enough said.
What they did was shrink each module to allow some of the background to bleed through. Which also makes their other claim that they do some halftoning thing quite irrelevant, you can have any color palette you want in the background (even full-on rgb). They are NOT part of the QR code, you just have to ensure the overall contrast of the module is distinguishable between the two states, conveniently achieved by the "ugly" black and white boxes dotted around the code. What this does is only make the code partially readable, because the scanner has a hard time interpreting a lot of the modules, and relies on error correction to recover the damaged parts.
They are not making the image into a QR code. Not a valid one anyway. They claim the code itself becomes the image, but it's really just a different way of partially damaging a valid QR code (spread the error over the whole area, instead of concentrating it in the middle). If it were a valid QR code, then a perfect picture of one (directly out of the generator, not taken from a photo, so it's as clean and perfect as can be) would be scanned correctly (most didn't) and it also does so with ZERO errors on any of the reed solomon blocks in the code. This project achieves nothing particularly interesting.
This is absolutely awesome!
Well done.
Thanks! :)