nayuki / QR-Code-generator

High-quality QR Code generator library in Java, TypeScript/JavaScript, Python, Rust, C++, C.
https://www.nayuki.io/page/qr-code-generator-library
5.2k stars 1.11k forks source link

QrCode Renderer #205

Closed chubbard closed 2 weeks ago

chubbard commented 3 weeks ago

Adds a class that encapsulates rendering QRCodes to BufferedImage, bitmap to a java.lang.File, SVG, and bitmaps to OutputStream. This makes it really simple to render QRCode out of the box without needing understand the details of graphics, image formats, and details of the library. Here is a simple example:

 QrCode qr = QrCode.encodeText( "Hello World!", QrCode.Ecc.MEDIUM );
 File target = new QrCodeRenderer().renderFile(qrCode, "png", new File("output.png"));
chubbard commented 3 weeks ago

For your review to enhance QR-Code-Generator with out of the box rendering.

nayuki commented 3 weeks ago

Image output is a feature that was removed several years ago to avoid favoring any particular format. Please consult the commit history.

chubbard commented 3 weeks ago

Adding this PR would make your library more developer friendly. Why not include it? It would be like going to a sushi restaurant and they tell you they removed the rice from their sushi because they didn't want you to favor any particular rice. So you need to bring your own rice. Pretty sure people would see that as obtuse logic bordering on illogical and not a real reason to remove the rice. Plus including a mechanism to render the QR Code doesn't prevent anyone from making their own version should they see fit to do that. Obviously if I can create this representation anyone has the ability to create additional renderers. By including this renderer you aren't stopping people from making other renderers. So why prevent people from contributing useful things to your library?

nayuki commented 2 weeks ago

I will not try to explain everything as this topic has been rehashed quite a few times over the history of the project. If you want to dig deeper, look at:

You're looking at it with the view that more is better - you can just ignore any parts you don't need.
I'm looking at it with the view that less is better - less liability, less bugs, less to maintain.

Output formats have sparked endless discussions and feature/change requests in the past - "what about custom colors?", "what about different pixel shapes?", "what about my way of writing an SVG?", "what about scaling?". The use of java.awt.BufferedImage caused problems with Android, and removing that dependency has helped on that platform. Today's image formats might be PNG and SVG, but a few decades ago it was GIF and WMF or EPS. Some day, this might change as well.

Your analogy with a sushi restaurant is a bit ridiculous, as there is a norm in food service to receive ready-to-eat food. There is no such norm in this library. On the other hand, if you're saying that "restaurants should be opinionated in making a choice of rice for their users", then I will say "I am being opinionated by refusing to give preferential status to any particular image export format".

chubbard commented 2 weeks ago

I liked your reference to "ready-to-eat-food" because that is exactly how I see your library's requirements than a philosophy on "bigger is better." I appreciate keeping the feature set minimized to keep the library focused on doing one thing well and keeping it practically oriented. But, I don't see this as more is better, but more keeps it targeted towards practicality. The library is not useful until you can visualize the QrCode. That's the minimal feature set that delivers something useful. Or more straight forwardly stated allows the consumer of this lib to deliver their feature. This addition would only help fulfill the needs of what most people require. This PR just takes a stab about what is most likely to be required. Your point about java.awt.BufferedImage is valid, but there are solutions to it. I can tell you are tired of explaining your decision over and over, but if you have to keep explaining it maybe it's important and could warrant reconsidering your position. There is a difference between being opinionated and obstinate, and usually the difference is misplaced dogma.

In the end if you reject this PR, which is well within your right to do so, I can release it as a separate library that uses your lib to make it easier for people to consume. I appreciate you taking the time to respond to me and discuss your choices for your library. Thank you.