1

Im trying to get the generated image from PHP via ajax.

Q.1 When ajax renders PHP it shows some symbols not the picture which it shows when PHP is run alone. How to i get the image PHP outputs and not those symbols?

Q2. How do i change the font size of the text rendered into the image?

PHP.

$im    = imagecreate(300, 20);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im,   0,   0,   0);
imagestring($im, 5, 15, 1, '564545446', $black);
header ('Content-type: image/png');
imagepng($im, null, 3);

Ajax:

$.CaptchaLoad = function(){
$.ajax({
    type:"POST",
    complete: function(){
        },
    url:"../php/captcha.php"
    }).done(function(feedback){
    $('.CaptchaImg').html(feedback) 
});
}
Giacomo1968
  • 23,903
  • 10
  • 59
  • 92
user3109875
  • 788
  • 10
  • 32
  • 1
    Remove the echo statement. The imagepng with the content declaration will send the appropriate headers back to the browser indicating how to render the data. However, as you have it, this will not work because you're sending back a content type as the source of the image in your echo. – Ohgodwhy Dec 29 '13 at 06:54
  • First of all, `$img` should contain a filename, not a header information. Second - just remove an Ajax. What you want to achieve can be done without it. – BlitZ Dec 29 '13 at 06:54
  • @HAL9000 No i corrected the code, it was messed up when i was doing tests. Let's work with the corrected new code. – user3109875 Dec 29 '13 at 07:00
  • @Ohgodwhy i edited the code, please look at it again. – user3109875 Dec 29 '13 at 07:01
  • 1
    you can try base64 string as image. – talsibony Dec 29 '13 at 07:17

3 Answers3

1

Answer #1:

  1. Add tag with <img id="capcha" src="../php/captcha.php" height="30" width="300"/> your .CaptchaImg container.
  2. Use reload handler for capcha load like this:

    $.CaptchaLoad = function(){
        var src   = '../php/captcha.php',
            stamp = (new Date()).getTime(),
            url   = src + '?' + stamp;
    
        document.getElementById('capcha').src = url;
    };
    

Useful link: Refresh image with a new one at the same url.


Answer #2:

You may use another parameters to change font size. For example add GET-parameter to image load script. Then capture it on server and react while you rendering capcha image.

Client-side:

$.CaptchaLoad = function(){
    var src   = '../php/captcha.php',
        stamp = (new Date()).getTime(),
        font  = 15, // or get it from somewhere else
        url   = src + '?stamp=' + stamp + '&font=' + font,
        img   = document.getElementById('capcha');

    img.src       = url;
    img.className = 'capcha-loading';
    img.onload    = function(){ this.className = ''; };
    img.onerror   = function(){ this.className = 'capcha-error'; };
};

Server-side:

$font = isset($_GET['font']) ? abs((int)$_GET['font']) : 15;
//                                      ^                ^
//                                asked font size      default

// ... render image using obtained font size

P.S.: Also, you have forgot to use imagedestroy($im); in the end of PHP script.

Community
  • 1
  • 1
BlitZ
  • 11,576
  • 3
  • 44
  • 62
  • I like this answer, so but now how do i attach the complete or success so i can show some loading gif. – user3109875 Dec 29 '13 at 07:27
  • @user3109875 `document.getElementById('capcha')` has `onload` and `onerror` events, no? – BlitZ Dec 29 '13 at 07:28
  • There ins't? Now that's a problem. – user3109875 Dec 29 '13 at 07:31
  • @user3109875 I mean, you may use those event handlers to indicate progress. For example attach css-class, before loading starts, then remove it in `onload` handler, or change in `onerror` handler. – BlitZ Dec 29 '13 at 07:34
1

this is your problem:

    $('.CaptchaImg').html(feedback);

It should get html code but it gets png file which should be the src attribute of the img tag because you just echo it so in the first place you can use the image src as your captcha.php.

I believe you want to do ajax in order to refresh it without refreshing all page You can send a base64 string image

$im    = imagecreate(300, 20);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im,   0,   0,   0);
imagestring($im, 5, 15, 1, '564545446', $black);
imagestring($im, 5, 15, 1, '564545446', $black);
ob_start();
imagepng($im);
$imagestring = ob_get_contents();
ob_end_clean();

echo 'data:image/jpeg;base64, '.base64_encode($imagestring);

imagedestroy($im);

fix your ajax

    $.ajax({
        type:"POST",
        complete: function(base64image){
            },
        url:"../php/captcha.php"

    }).done(function(base64image){
                 $('.captch').attr('src',base64image);
});
talsibony
  • 7,378
  • 5
  • 42
  • 41
0

Rather than send "Content-type: image/png" to ajax, try to send HTML. Change your captcha.php code :

echo sprintf("<img src=\"%s\">", generate_img()); //return html to ajax

function generate_img() {
        $im = imagecreate(300, 20);
        $white = imagecolorallocate($im, 255, 255, 255);
        $black = imagecolorallocate($im, 0, 0, 0);
        imagestring($im, $_POST["font_size"], 15, 1, $_POST["text"], $black);
        imagepng($im, null, 3);

        header('Content-type: image/png');
        echo $im;

}

in ajax :

$.ajax({
    type:"POST",
    data{
      text : "My text",
      font_size : 5
    }
    complete: function(){
        },
    url:"../php/captcha.php"
    }).done(function(img){
    $('.CaptchaImg').html(img); //.CaptchaImg can be a DIV element
});
Harry S
  • 256
  • 2
  • 4