chemlv / cool-php-captcha

Automatically exported from code.google.com/p/cool-php-captcha
GNU General Public License v3.0
0 stars 0 forks source link

Transparent background - possible? #14

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
I tried changing the line around 287, from:
        $this->im = imagecreatetruecolor($this->width*$this->scale, $this->height*$this->scale);

        // Background color
        $this->GdBgColor = imagecolorallocate($this->im,
            $this->backgroundColor[0],
            $this->backgroundColor[1],
            $this->backgroundColor[2]
        );
        imagefilledrectangle($this->im, 0, 0, $this->width*$this->scale, $this->height*$this->scale, $this->GdBgColor);

to:

        $this->im = imagecreatetruecolor($this->width*$this->scale, $this->height*$this->scale);
        $color = $this->create_color($this->im, null, 0);
        imagesavealpha($this->im, true);
        // Set the blending mode to false, add the bgcolor, then switch it back.
        imagealphablending($this->im, false);
        imagefilledrectangle($this->im, 0, 0, $this->width, $this->height, $color);
        imagealphablending($this->im, true);

What is the expected output? What do you see instead?
But I'm not getting anything good, background is either black, or captcha is 
not beeings seen at all, I have tied different combos, but no luck :(

What version of the product are you using? On what operating system?
Version is 0.3, Linux, PHP 5.3

Thank you for your help !

Original issue reported on code.google.com by hugles...@gmail.com on 21 Mar 2011 at 7:05

GoogleCodeExporter commented 9 years ago
Forgot to paste the create_color() function:

    protected function create_color(&$image, $hex, $alpha)
    {
        if ($hex == null)
        {
            $red = 0;
            $green = 0;
            $blue = 0;
            $alpha = 127;
        }
        else
        {
            // Check if theres a # in front
            if (substr($hex, 0, 1) == '#')
                $hex = substr($hex, 1);
            // Break apart the hex
            if (strlen($hex) == 6)
            {
                $red = hexdec(substr($hex, 0, 2));
                $green = hexdec(substr($hex, 2, 2));
                $blue = hexdec(substr($hex, 4, 2));
            }
            else
            {
                $red = hexdec(substr($hex, 0, 1).substr($hex, 0, 1));
                $green = hexdec(substr($hex, 1, 1).substr($hex, 1, 1));
                $blue = hexdec(substr($hex, 2, 1).substr($hex, 2, 1));
            }
            $alpha = 127 - floor($alpha * 1.27);
        }
        // Check if the transparency is allowed
        return imagecolorallocatealpha($image, $red, $green, $blue, $alpha);
    }

Original comment by hugles...@gmail.com on 21 Mar 2011 at 7:22

GoogleCodeExporter commented 9 years ago

Original comment by joserodr...@gmail.com on 22 Mar 2011 at 5:34

GoogleCodeExporter commented 9 years ago
I downloaded version 0.3 yesterday and have a working transparent png, high 
quality output, semi-transparent text, loading between 1-4ms (faster than the 
default 18+ms on a scale of 3). Adding blur increases loading time between 
6-8ms.

The problem lies where the image is copied and resampled. This breaks any sort 
of transparency. My first step was to disable the functions WaveImage() and 
RedeuceImage(). Eliminating these functions meant I need to reconfigure my 
scale or hard code a new width and height. I decided to set the scale to 1.

* Note: disabling WaveImage() and RedeuceImage() does not interfere with the 
warping of the text

The function ImageAllocate() needed to be modified slightly. The original GD 
functions used to create the colours, imagecolorallocate, I changed to 
imagecolorallocatealpha, which allows for a transparency setting. Easy. This 
along with other modifications allowed me to create the perfect captcha for my 
site.

Obviously this goes for PNG only, not JPEG.

Direct edits:

public $scale = 1;

...

public $imageFormat = 'png';

...

    public function CreateImage() {
        $ini = microtime(true);

        /** Initialization */
        $this->ImageAllocate();

        /** Text insertion */
        $text = $this->GetCaptchaText();
        $fontcfg  = $this->fonts[array_rand($this->fonts)];
        $this->WriteText($text, $fontcfg);

        $_SESSION[$this->session_var] = $text;

        /** Transformations */
        // Do not run this function
        //$this->WaveImage();
        if ($this->blur && function_exists('imagefilter')) {
            imagefilter($this->im, IMG_FILTER_GAUSSIAN_BLUR);
        }
        // Do not run this function
        //$this->ReduceImage();

        if ($this->debug) {
            imagestring($this->im, 1, 1, $this->height-8,
                "$text {$fontcfg['font']} ".round((microtime(true)-$ini)*1000)."ms",
                $this->GdFgColor
            );
        }

        /** Output */
        $this->WriteImage();
        $this->Cleanup();
    }

...

    protected function ImageAllocate() {
        // Cleanup
        if (!empty($this->im)) {
            imagedestroy($this->im);
        }

        $this->im = imagecreatetruecolor($this->width*$this->scale, $this->height*$this->scale);

        // Background color
        $this->GdBgColor = imagecolorallocatealpha($this->im,
            $this->backgroundColor[0],
            $this->backgroundColor[1],
            $this->backgroundColor[2],
            127
        );
        imagealphablending($this->im, false);
        imagesavealpha($this->im, true);
        imagefilledrectangle($this->im, 0, 0, $this->width*$this->scale, $this->height*$this->scale, $this->GdBgColor);

        // Foreground color
        $color           = $this->colors[mt_rand(0, sizeof($this->colors)-1)];
        $this->GdFgColor = imagecolorallocatealpha($this->im, $color[0], $color[1], $color[2], 30);

        // Shadow color
        if (!empty($this->shadowColor) && is_array($this->shadowColor) && sizeof($this->shadowColor) >= 3) {
            $this->GdShadowColor = imagecolorallocate($this->im,
                $this->shadowColor[0],
                $this->shadowColor[1],
                $this->shadowColor[2]
            );
        }
    }

Original comment by thats...@gmail.com on 20 Jul 2011 at 4:25

GoogleCodeExporter commented 9 years ago
Oh I made a slight error in the ImageAllocate() function. In order to blend the 
text together nicely, imagealphablending needs to be set back to true.

Here is the correction:

    protected function ImageAllocate() {
        // Cleanup
        if (!empty($this->im)) {
            imagedestroy($this->im);
        }

        $this->im = imagecreatetruecolor($this->width*$this->scale, $this->height*$this->scale);

        // Background color
        $this->GdBgColor = imagecolorallocatealpha($this->im,
            $this->backgroundColor[0],
            $this->backgroundColor[1],
            $this->backgroundColor[2],
            127
        );
        imagealphablending($this->im, false);
        imagesavealpha($this->im, true);
        imagefilledrectangle($this->im, 0, 0, $this->width*$this->scale, $this->height*$this->scale, $this->GdBgColor);
        imagealphablending($this->im, true);

        // Foreground color
        $color           = $this->colors[mt_rand(0, sizeof($this->colors)-1)];
        $this->GdFgColor = imagecolorallocatealpha($this->im, $color[0], $color[1], $color[2], 30);

        // Shadow color
        if (!empty($this->shadowColor) && is_array($this->shadowColor) && sizeof($this->shadowColor) >= 3) {
            $this->GdShadowColor = imagecolorallocatealpha($this->im,
                $this->shadowColor[0],
                $this->shadowColor[1],
                $this->shadowColor[2],
                0
            );
        }
    }

Original comment by thats...@gmail.com on 20 Jul 2011 at 5:43

GoogleCodeExporter commented 9 years ago
Hello,

I really appreciate you have taken the time to respond to the issue. I must say 
it works in easy steps!

I have replaced those two methods you provided, and everything is working 
really nicely.

I think something like this might go to the core?

Thanks once again!

cheers,
Jaroslav

Original comment by hugles...@gmail.com on 20 Jul 2011 at 8:58

GoogleCodeExporter commented 9 years ago
Hey no problem. I doubt this will be apart of the core because the warping of 
the image text adds to the complexity and is really essential to the security 
aspect. I've spent most of my time reading the PHP.net manual about this and it 
seems that when an image is copied or resampled, transparency fails. I figured 
it out in about 2 hours - I'm no pro at anything GD.

Custom sites like ours can probably get by with not having extremely warped 
text like the demo provides but the majority of sites will be able to still 
look cosmetically good with a white background, which can of course be 
customized to match a colour scheme of said web site.

Hopefully an update to the GD or freetype libraries will be better able to 
create transparent PNGs.

Original comment by thats...@gmail.com on 21 Jul 2011 at 2:18

GoogleCodeExporter commented 9 years ago

Thank you guys for your feedback.

After busy months at University and then holidays I'm back again.
There are some issues with transparency specially in GIF format. Working on it 
:)

Original comment by joserodr...@gmail.com on 11 Oct 2011 at 6:50

GoogleCodeExporter commented 9 years ago
Hello,

When you will come with something, let us know too :) 
Currently I am using the code posted above, with no single issue.
I have not tried GIF, I use PNGs at the moment :) 

Thanks once again for the original live saver!

Jaroslav

Original comment by hugles...@gmail.com on 12 Oct 2011 at 7:24

GoogleCodeExporter commented 9 years ago
But, that code has a BIG issue: Currently could be possible to a machine decode 
the captcha, and that is totally unacceptable for a captcha.

The captcha should be "cool", but, first of all must to be secure.

Original comment by joserodr...@gmail.com on 14 Oct 2011 at 2:26

GoogleCodeExporter commented 9 years ago
<img id="captcha" src="<?php echo URL_ROOT; 
?>modules/module_contact/views/themes/captcha/captcha.php" style="width:200px;">

fix big image ====> css style="width:200px;"

Original comment by webgiare...@gmail.com on 4 Oct 2014 at 3:03