Dear John,

Thank you again for this patch. It is now included in the SVN trunk and in the latest 1.13.5 release.

In my installation, only imagefilter was missing - but I have discovered that this is more of a rarity than I initially suspected. I was happy to include the patch as is.

Regards,
Adam Zammit


On 20 October 2012 18:11, John Milner <jmilner@cristoreyny.org> wrote:
Dear Adam,

How about something like this? Folks without the necessary functions
available should notice no difference.

In your testing, was only imagefilter() absent, or was any of the rest
unavailable as well? If it's only imagefilter(), I could certainly
write up a version that uses the homegrown blurring method you shared
back in March.

Thank you,

John


--- quexf-1.13.4/functions/functions.barcode.php        2012-10-19
16:44:40.000000000 -0400
+++ quexf-1.13.4-modified/functions/functions.barcode.php       2012-10-20
03:04:06.000000000 -0400
@@ -216,6 +216,21 @@
  */
 function barcode($image, $step = 1, $length = false)
 {
+       if (function_exists('imagefilter') &&
+           function_exists('imagetruecolortopalette') &&
+           function_exists('imagecolorset') &&
+           function_exists('imagecolorclosest'))
+       {
+               //Gaussian blur to fill in holes from dithering
+               imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
+               //force two colors; dithering = FALSE
+               imagetruecolortopalette($image, FALSE, 2);
+               //find the closest color to black and replace it with actual black
+               imagecolorset($image, imagecolorclosest($image, 0, 0, 0), 0, 0, 0);
+               //find the closest color to white and replace it with actual white
+               imagecolorset($image, imagecolorclosest($image, 255, 255, 255),
255, 255, 255);
+       }
+
        //search

        $height = imagesy($image);


On Tue, Oct 16, 2012 at 6:17 PM, Adam Zammit <adam.zammit@acspri.org.au> wrote:
>
> Dear John,
>
> Thanks for following up on this. On one of my older servers running an
> outdated Debian the imagefilter function is not supported, but it
> appears to be available in all my newer environments. I'd gladly
> review a patch if you could send that through. Ideally it should not
> fail if the imagefilter function is not available.
>
> Regards,
> Adam Zammit
>
> On 15 October 2012 21:13, John Milner <jmilner@cristoreyny.org> wrote:
> > Dear Adam,
> >
> > Back in March, David Burke posted some code that I'd written in
> > attempt to mitigate the nasty effects of dithering on barcode
> > recognition. I failed to respond to your question about alternative
> > graphics functions, but I'd like to revisit that discussion now.
> >
> > I see that "PHP 5 with GD extension" is now listed in the queXF
> > requirements per http://quexf.sourceforge.net/node/12. On Debian and
> > derivatives, is the GD dependency satisfied by the php5-gd package? If
> > so, I think all users should have imagefilter(),
> > imagetruecolortopalette(), imagecolorset(), and imagecolorclosest()
> > available. This is the case for me on Debian 6.0.6; would you mind
> > checking in your environment? Here's a little blurb to help make it as
> > quick as possible:
> > <?php
> >         $functions = Array('imagefilter', 'imagetruecolortopalette',
> > 'imagecolorset', 'imagecolorclosest');
> >         foreach($functions as $f)
> >         {
> >                 echo $f . '()? ' . (function_exists($f) ? 'yes' : 'no') . "\n";
> >         }
> > ?>
> >
> > Provided you're convinced that using these functions won't isolate
> > users, and that you're still amenable to adding my code, I'll test
> > everything with the newest version of queXF and send you a proper
> > patch.
> >
> > Thanks for your consideration.
> >
> > John Milner
> >
> > ---------- Forwarded message ----------
> > From: Adam Zammit <adam.zammit@acspri.org.au>
> > Date: Thu, Mar 22, 2012 at 9:35 PM
> > Subject: Re: [Quexf-discuss] improved barcode reading
> > To: David Burke <david@burkesoftware.com>
> > Cc: quexf-discuss@lists.sourceforge.net, John Milner
> > <jmilner@cristoreyny.org>
> >
> >
> > Dear David and John,
> >
> > Thanks for that detailed description and the updated code.
> >
> > I've had a look at the code and did some testing. On my installation (and I
> > expect others) who use pre-packaged PHP installations via Debian/Ubuntu -
> > the imagefilter function is not available (as GD is linked in - not compiled
> > with the bundle that comes with PHP).
> >
> > I tested it using the code from here instead to execute the blur:
> >
> > http://www.puremango.co.uk/2009/04/php-4-and-5-image-blur/
> >
> > And the results were ok - but I'd like to confirm that they were as good as
> > your example. If you have a chance to check it out using that function (or
> > one similar) that doesn't depend on imagefilter or imageconvolution
> > (functions that are only available if PHP is compiled with the bundled
> > version of the GD library) - I'd be greatly appreciative and would be able
> > to include it in queXF as it won't isolate any users.
> >
> > Regards,
> > Adam Zammit
> >
> >
> > On 9 March 2012 14:27, David Burke <david@burkesoftware.com> wrote:
> >>
> >> cc'ed John Milner who helped develop this.
> >>
> >> As for the iterations we thought about doing a couple but it appears
> >> unnecessary in my scans. I wonder if the blur could ever cause issues. In my
> >> cases it doesn't. Might not be a bad idea to have it configurable though.
> >>
> >> Doing the blur when not needed takes extra cpu time. We could scan first
> >> and blur on fail. This would be the least error prone but would take more
> >> cpu time in cases where blur is usually needed.
> >>
> >> Here is a revised version that is slightly more efficient and yields a
> >> true monochrome image.
> >>
> >> //Gaussian blur to fill in holes from dithering
> >> imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
> >> //force two colors; dithering = FALSE
> >> imagetruecolortopalette($image, FALSE, 2);
> >> //find the closest color to black and replace it with actual black
> >> imagecolorset($image, imagecolorclosest($image, 0, 0, 0), 0, 0, 0);
> >> //find the closest color to white and replace it with actual white
> >> imagecolorset($image, imagecolorclosest($image, 255, 255, 255), 255, 255,
> >> 255);
> >>
> >> This is probably all you need to know but if you're curious John wrote up
> >> a detailed analysis of the strangeness of PHP's GD implementation.
> >>
> >>> Really, like you said, the contrast filter's only job is to force every
> >>> pixel to be either black (R=G=B=0) or white (R=G=B=255). But why is such an
> >>> extreme value required to achieve that? And is it extreme enough?
> >>>
> >>> I had a look at the source. PHP's version of libgd defines
> >>> gdImageContrast(), which doesn't exist in upstream libgd, to do the contrast
> >>> adjustment work. Given a contrast adjustment value x, gdImageContrast()
> >>> applies this formula to each component color, c, of each pixel:
> >>>
> >>>
> >>> Since the goal is to force everything to either black or white, the edge
> >>> cases are c = 127 and c = 128. For c <= 127, the resulting component color
> >>> value should be 0:
> >>>
> >>> There are two solutions:
> >>>
> >>>
> >>> Rounded to integers, these are -1497 and 1697, respectively. It's okay
> >>> that these are larger in magnitude than the actual solutions. Anything less
> >>> the negative solution or greater than the positive solution will yield a
> >>> value outside the range 0..255, and gdImageContrast() will attenuate the
> >>> result so it fits within 8 bits.
> >>>
> >>> For c >= 128, the result should be 255:
> >>>
> >>> The solutions are the same.
> >>>
> >>> To me, this is a totally bizarre function. I think it would be hilarious
> >>> to see in the PHP documentation something like "The useful range of arg1 is
> >>> -1497 to 1697. IMG_FILTER_CONTRAST behaves symmetrically about arg1 = 100."
> >>>
> >>> For queXF, we should either up the value to 1697 (or down it to -1497),
> >>> or probably just avoid the contrast filter altogether. Here's an
> >>> alternative:
> >>> //Gaussian blur to fill in holes from dithering
> >>> imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
> >>> //force two colors; dithering = FALSE
> >>> imagetruecolortopalette($image, FALSE, 2);
> >>> //find the closest color to black and replace it with actual black
> >>> imagecolorset($image, imagecolorclosest($image, 0, 0, 0), 0, 0, 0);
> >>> //find the closest color to white and replace it with actual white
> >>> imagecolorset($image, imagecolorclosest($image, 255, 255, 255), 255, 255,
> >>> 255);
> >>>
> >>> Note that this method yields an actual 1-bit black and white image, not a
> >>> true-color image that merely has black and white pixels. Please test it to
> >>> make sure queXF doesn't choke.
> >>>
> >>> In case you were wondering, the sensible way is slightly faster. Here's
> >>> the old contrast filter method:
> >>>>
> >>>> 0.16user 0.01system 0:00.18elapsed 96%CPU (0avgtext+0avgdata
> >>>> 11416maxresident)k
> >>>> 0inputs+16outputs (0major+3370minor)pagefaults 0swaps
> >>>
> >>> And the alternative palette reduction method:
> >>>>
> >>>> 0.10user 0.01system 0:00.11elapsed 97%CPU (0avgtext+0avgdata
> >>>> 12996maxresident)k
> >>>> 0inputs+8outputs (0major+3765minor)pagefaults 0swaps
> >>
> >>
> >> David Burke
> >> Software Engineer and Founder
> >> Burke Software and Consulting LLC
> >> For help requests, email help@burkesoftware.com
> >> Watch announcements on Google Plus
> >>
> >>
> >>
> >> On Thu, Mar 8, 2012 at 9:54 PM, Adam Zammit <adam.zammit@acspri.org.au>
> >> wrote:
> >>>
> >>> Dear David,
> >>>
> >>> That looks very valuable. I do see problems like this when people scan in
> >>> grayscale instead of b&w also - and the ghostscript conversion to a 1 bit
> >>> image file is full of pock-marks as appears in your example.
> >>>
> >>> I will test the code below with the aim of including it in queXF - can
> >>> you please let me know if the loop you had there was just for debugging - or
> >>> will there be some value in being able to increase kludge_iterations?
> >>>
> >>> Regards,
> >>> Adam Zammit
> >>>
> >>>
> >>> On 7 March 2012 09:55, David Burke <david@burkesoftware.com> wrote:
> >>>>
> >>>> Adam,
> >>>>
> >>>> I was able to improve barcode reading accuracy to a good degree. Would
> >>>> you want to include this in quexf, perhaps as a configurable option? Before
> >>>> I had issues where some printers leaving "salt and pepper" marks on a scan
> >>>> that would break it.
> >>>>
> >>>> In functions.barcode.php in the barcode function I added
> >>>>
> >>>>         //imagepng($image, "/var/www/auto_before.png");
> >>>>         $kludge_iterations = 1;
> >>>>         for ($i = 0; $i < $kludge_iterations; $i += 1)
> >>>>         {
> >>>>                 imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
> >>>>                 imagefilter($image, IMG_FILTER_CONTRAST, -1000);
> >>>>         }
> >>>>         //imagepng($image, "/var/www/auto_after.png");
> >>>>
> >>>> I saw you had a kfill_modified function for ocr. I tried this and it
> >>>> improved it but the Gaussian blur effect seems to be quicker and more
> >>>> effective.
> >>>>
> >>>> Attached are before and after effects. On paper and to the human eye
> >>>> there the barcode does not have any holes. They are defects from a scanner.
> >>>> Of 3 scanners I tested only 1 has this issue. One the troubled scanner I was
> >>>> able to get it to work usually by tweaking contrast settings, however a
> >>>> software fix is far more reliable.
> >>>>
> >>>> Best,
> >>>>
> >>>> David Burke
> >>>> Software Engineer and Founder
> >>>> Burke Software and Consulting LLC
> >>>> For help requests, email help@burkesoftware.com
> >>>> Watch announcements on Google Plus
> >>>>
> >>>>
> >>>>
> >>>> ------------------------------------------------------------------------------
> >>>> Keep Your Developer Skills Current with LearnDevNow!
> >>>> The most comprehensive online learning library for Microsoft developers
> >>>> is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
> >>>> Metro Style Apps, more. Free future releases when you subscribe now!
> >>>> http://p.sf.net/sfu/learndevnow-d2d
> >>>> _______________________________________________
> >>>> Quexf-discuss mailing list
> >>>> Quexf-discuss@lists.sourceforge.net
> >>>> https://lists.sourceforge.net/lists/listinfo/quexf-discuss
> >>>>
> >>>
> >>>
> >>>
> >>> --
> >>> Adam Zammit
> >>> Research and Development Officer
> >>> Australian Consortium for Social and Political Research Inc.
> >>> +61 3 9013 9653
> >>> http://www.acspri.org.au/
> >>
> >>
> >
> >
> >
> > --
> > Adam Zammit
> > Research and Development Officer
> > Australian Consortium for Social and Political Research Inc.
> > +61 3 9013 9653
> > http://www.acspri.org.au/
> >
> > ------------------------------------------------------------------------------
> > Don't let slow site performance ruin your business. Deploy New Relic APM
> > Deploy New Relic app performance management and know exactly
> > what is happening inside your Ruby, Python, PHP, Java, and .NET app
> > Try New Relic at no cost today and get our sweet Data Nerd shirt too!
> > http://p.sf.net/sfu/newrelic-dev2dev
> > _______________________________________________
> > Quexf-discuss mailing list
> > Quexf-discuss@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/quexf-discuss
>
>
>
> --
> Adam Zammit
> Research and Development Officer
> Australian Consortium for Social and Political Research Inc.
> +61 3 9013 9653
> http://www.acspri.org.au/



--
Adam Zammit
Research and Development Officer
Australian Consortium for Social and Political Research Inc.
+61 3 9013 9653
http://www.acspri.org.au/