Bacon / BaconQrCode

QR Code Generator for PHP
BSD 2-Clause "Simplified" License
1.86k stars 212 forks source link

Add GD Image backend #114

Closed arxeiss closed 7 months ago

arxeiss commented 2 years ago

My client's web hosting provider sucks, and they don't have support for Imagick, even though they are promising it will be added.

I'm generating QR codes for payment, which is added into email body. And email client's do not have nice support for SVG. So I need old-school GD support.

However, GD has limited sets of functions. I believe, that it is OK, when that backend will have also limited sets of features. So this is not supported:

And because GD does not support Paths like Imagick or SVG do, I need to generate a bit different paths, so they are not so complex.

DASPRiD commented 2 years ago

Well, I can understand not supporting gradients through this backend, as that would require pixel-level control, which is extremely slow to do in PHP. Though general paths shouldn't be an issue:

A very primitive approach could use imagefilledpolygon and calculate a close enough approximation of points beforehand based on the given path, that would be possible with relatively simple calculations.

codecov-commenter commented 2 years ago

Codecov Report

Merging #114 (e41b372) into master (5c2d190) will increase coverage by 3.41%. The diff coverage is 82.41%.

@@             Coverage Diff              @@
##             master     #114      +/-   ##
============================================
+ Coverage     63.42%   66.83%   +3.41%     
- Complexity      928      988      +60     
============================================
  Files            47       48       +1     
  Lines          2783     2946     +163     
============================================
+ Hits           1765     1969     +204     
+ Misses         1018      977      -41     
Impacted Files Coverage Δ
src/Renderer/Eye/CompositeEye.php 0.00% <0.00%> (ø)
src/Renderer/Image/EpsImageBackEnd.php 0.00% <0.00%> (ø)
src/Renderer/Image/SvgImageBackEnd.php 0.00% <0.00%> (ø)
src/Renderer/Eye/SimpleCircleEye.php 11.53% <50.00%> (+11.53%) :arrow_up:
src/Renderer/Eye/SquareEye.php 96.00% <83.33%> (-4.00%) :arrow_down:
src/Renderer/Image/GDImageBackEnd.php 84.37% <84.37%> (ø)
src/Renderer/Eye/ModuleEye.php 100.00% <100.00%> (ø)
src/Renderer/Image/ImagickImageBackEnd.php 63.69% <100.00%> (+0.46%) :arrow_up:
src/Renderer/ImageRenderer.php 94.73% <100.00%> (+0.19%) :arrow_up:
src/Renderer/Module/DotsModule.php 95.83% <100.00%> (+95.83%) :arrow_up:
... and 10 more

Help us with your feedback. Take ten seconds to tell us how you rate us.

arxeiss commented 2 years ago

I was trying to do that, but I don't know how to solve subtraction. Because there is EdgeIterator and getSimplifiedPoints which returns path like this example below.

There is an outer path and inside is an inner path. And the inner one subtracts from the outer one. Look at this SVG

<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
  <path fill="#7e7e7e" fill-rule="evenodd" d="M131 55 L245 55 L245 154 L114 159 Z
    M169 79 L206 78 L206 121 L158 122 L169 79 Z"></path>
</svg>

Result will look like this

image

So I'm not sure how I would be able to use imagefilledpolygon because when I draw an outer path, it fills it completely. And then I would have to somehow delete the inner path. And those paths can intersect just partially. And there might be multiple nested paths.

If you know how to handle this with imagefilledpolygon, please give me some hint. Because that is what I was trying to do last 3 days.

DASPRiD commented 2 years ago

Maybe this might be of help (README states that he never finished the code for the path, but might be good guidance):

https://github.com/stefanak-michal/SvgRenderer/blob/master/Shapes.php#L318-L419

Maybe there are other libraries out there as well, who knows :)

DASPRiD commented 2 years ago

Here's another library which seems to be actually maintained:

https://github.com/meyfa/php-svg/tree/main/src/Rasterization/Path

arxeiss commented 2 years ago

PHP-SVG seems interesting. Will take a look at it, how and if it works.

arxeiss commented 2 years ago

So I did some checks and it seems promising.

However, latest release is v0.11.3 (from February), which is failing to draw nested paths. The latest master works better, all QR codes were OK. But there is minor issue with scaling.

So when they will release new version, I can rewrite that to use PHP-SVG library. I don't think that writing own rasterizer is a good idea. It is quite complex and it would require maintenance as well.

DASPRiD commented 1 year ago

An alternative would be to not use the ImageRenderer with all its features at all for GDLib, but implement a GDLibRenderer which doesn't have any styling support at all.

arxeiss commented 1 year ago

I see that PHP-SVG released new version couple of hours ago. I will check that.

But what you are suggesting might be better solution. Even I would integrate PHP-SVG, it would not support Gradients anyway.

arxeiss commented 1 year ago

I changed implementation including README. So no hacks across all files, but a completely new rendered is added. Please check it now. Thanks

DASPRiD commented 7 months ago

@arxeiss Excuse the extremely long wait. I'm preparing a new major release now. Could you adjust your PR to use PHP 8.1 features?

See changes introduced by #157

arxeiss commented 7 months ago

Closing in favor of #159