captcha image is display - php

I have code which display captcha in my local machine. But when I put that code in server then captcha image not working. Please any body solve my problem. My local machine is ubuntu 12.04, and server machine is ubuntu 14.04. Below is my code.
demo.php
<?php session_start();
if(isset($_POST['Submit'])){
// code for check server side validation
if(empty($_SESSION['captcha_code'] ) || strcasecmp($_SESSION['captcha_code'], $_POST['captcha_code']) != 0){
$msg="<span style='color:red'>The Validation code does not match!</span>";// Captcha verification is incorrect.
}else{// Captcha verification is Correct. Final Code Execute here!
$msg="<span style='color:green'>The Validation code has been matched.</span>";
}
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>PHP Secure Professional Captcha.</title>
<link href="./css/stylecaptcha.css" rel="stylesheet">
<script type='text/javascript'>
function refreshCaptcha(){
var img = document.images['captchaimg'];
img.src = img.src.substring(0,img.src.lastIndexOf("?"))+"?rand="+Math.random()*1000;
}
</script>
</head>
<body>
<br>
<form action="" method="post" name="form1" id="form1" >
<table width="400" border="0" align="center" cellpadding="5" cellspacing="1" class="table">
<?php if(isset($msg)){?>
<tr>
<td colspan="2" align="center" valign="top"><?php echo $msg;?></td>
</tr>
<?php } ?>
<tr>
<td align="right" valign="top"> Validation code:</td>
<td><img src="captcha.php?rand=<?php echo rand();?>" id='captchaimg'><br>
<label for='message'>Enter the code above here :</label>
<br>
<input id="captcha_code" name="captcha_code" type="text">
<br>
Cannot read the image? click <a href='javascript: refreshCaptcha();'>here</a> to refresh.</td>
</tr>
<tr>
<td> </td>
<td><input name="Submit" type="submit" onclick="return validate();" value="Submit" class="button1"></td>
</tr>
</table>
</form>
</body>
</html>
captcha.php
<?php
session_start();
include("./phptextClass.php");
/*create class object*/
$phptextObj = new phptextClass();
/*phptext function to genrate image with text*/
$phptextObj->phpcaptcha('#162453','#fff',120,40,10,25);
?>
phptextClass.php
<?php
/*phptext class, version 1.0
created by www.w3schools.in (Gautam kumar)
April 26, 2014
*/
class phptextClass
{
public function phptext($text,$textColor,$backgroundColor='',$fontSize,$imgWidth,$imgHeight,$dir,$fileName)
{
/* settings */
$font = './calibri.ttf';/*define font*/
$textColor=$this->hexToRGB($textColor);
$im = imagecreatetruecolor($imgWidth, $imgHeight);
$textColor = imagecolorallocate($im, $textColor['r'],$textColor['g'],$textColor['b']);
if($backgroundColor==''){/*select random color*/
$colorCode=array('#56aad8', '#61c4a8', '#d3ab92');
$backgroundColor = $this->hexToRGB($colorCode[rand(0, count($colorCode)-1)]);
$backgroundColor = imagecolorallocate($im, $backgroundColor['r'],$backgroundColor['g'],$backgroundColor['b']);
}else{/*select background color as provided*/
$backgroundColor = $this->hexToRGB($backgroundColor);
$backgroundColor = imagecolorallocate($im, $backgroundColor['r'],$backgroundColor['g'],$backgroundColor['b']);
}
imagefill($im,0,0,$backgroundColor);
list($x, $y) = $this->ImageTTFCenter($im, $text, $font, $fontSize);
imagettftext($im, $fontSize, 0, $x, $y, $textColor, $font, $text);
if(imagejpeg($im,$dir.$fileName,90)){/*save image as JPG*/
return json_encode(array('status'=>TRUE,'image'=>$dir.$fileName));
imagedestroy($im);
}
}
public function phpcaptcha($textColor,$backgroundColor,$imgWidth,$imgHeight,$noiceLines=0,$noiceDots=0,$noiceColor='#000000')
{
/* Settings */
$text=$this->random();
$font = './font/monofont.ttf';/* font */
$textColor=$this->hexToRGB($textColor);
$fontSize = $imgHeight * 0.75;
$im = imagecreatetruecolor($imgWidth, $imgHeight);
$textColor = imagecolorallocate($im, $textColor['r'],$textColor['g'],$textColor['b']);
$backgroundColor = $this->hexToRGB($backgroundColor);
$backgroundColor = imagecolorallocate($im, $backgroundColor['r'],$backgroundColor['g'],$backgroundColor['b']);
/* generating lines randomly in background of image */
if($noiceLines>0){
$noiceColor=$this->hexToRGB($noiceColor);
$noiceColor = imagecolorallocate($im, $noiceColor['r'],$noiceColor['g'],$noiceColor['b']);
for( $i=0; $i<$noiceLines; $i++ ) {
imageline($im, mt_rand(0,$imgWidth), mt_rand(0,$imgHeight),
mt_rand(0,$imgWidth), mt_rand(0,$imgHeight), $noiceColor);
}}
if($noiceDots>0){/* generating the dots randomly in background */
for( $i=0; $i<$noiceDots; $i++ ) {
imagefilledellipse($im, mt_rand(0,$imgWidth),
mt_rand(0,$imgHeight), 3, 3, $textColor);
}}
imagefill($im,0,0,$backgroundColor);
list($x, $y) = $this->ImageTTFCenter($im, $text, $font, $fontSize);
imagettftext($im, $fontSize, 0, $x, $y, $textColor, $font, $text);
imagejpeg($im,NULL,90);/* Showing image */
header('Content-Type: image/jpeg');/* defining the image type to be shown in browser widow */
imagedestroy($im);/* Destroying image instance */
if(isset($_SESSION)){
$_SESSION['captcha_code'] = $text;/* set random text in session for captcha validation*/
}
}
/*for random string*/
protected function random($characters=6,$letters = '23456789bcdfghjkmnpqrstvwxyz'){
$str='';
for ($i=0; $i<$characters; $i++) {
$str .= substr($letters, mt_rand(0, strlen($letters)-1), 1);
}
return $str;
}
/*function to convert hex value to rgb array*/
protected function hexToRGB($colour)
{
if ( $colour[0] == '#' ) {
$colour = substr( $colour, 1 );
}
if ( strlen( $colour ) == 6 ) {
list( $r, $g, $b ) = array( $colour[0] . $colour[1], $colour[2] . $colour[3], $colour[4] . $colour[5] );
} elseif ( strlen( $colour ) == 3 ) {
list( $r, $g, $b ) = array( $colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2] );
} else {
return false;
}
$r = hexdec( $r );
$g = hexdec( $g );
$b = hexdec( $b );
return array( 'r' => $r, 'g' => $g, 'b' => $b );
}
/*function to get center position on image*/
protected function ImageTTFCenter($image, $text, $font, $size, $angle = 8)
{
$xi = imagesx($image);
$yi = imagesy($image);
$box = imagettfbbox($size, $angle, $font, $text);
$xr = abs(max($box[2], $box[4]));
$yr = abs(max($box[5], $box[7]));
$x = intval(($xi - $xr) / 2);
$y = intval(($yi + $yr) / 2);
return array($x, $y);
}
}
?>

Related

Wordpress problem with header('Content-type: image/png');

i'am trying to put a CAPTCHA in a wordpress custom plugin.
I did follow that tutorial :
https://code.tutsplus.com/tutorials/build-your-own-captcha-and-contact-form-in-php--net-5362
<?php
session_start();
$permitted_chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
function generate_string($input, $strength = 10) {
$input_length = strlen($input);
$random_string = '';
for($i = 0; $i < $strength; $i++) {
$random_character = $input[mt_rand(0, $input_length - 1)];
$random_string .= $random_character;
}
return $random_string;
}
$image = imagecreatetruecolor(200, 50);
imageantialias($image, true);
$colors = [];
$red = rand(125, 175);
$green = rand(125, 175);
$blue = rand(125, 175);
for($i = 0; $i < 5; $i++) {
$colors[] = imagecolorallocate($image, $red - 20*$i, $green - 20*$i, $blue - 20*$i);
}
imagefill($image, 0, 0, $colors[0]);
for($i = 0; $i < 10; $i++) {
imagesetthickness($image, rand(2, 10));
$line_color = $colors[rand(1, 4)];
imagerectangle($image, rand(-10, 190), rand(-10, 10), rand(-10, 190), rand(40, 60), $line_color);
}
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$textcolors = [$black, $white];
$fonts = [dirname(__FILE__).'/Acme.ttf'];
$string_length = 6;
$captcha_string = generate_string($permitted_chars, $string_length);
$_SESSION['captcha_text'] = $captcha_string;
for($i = 0; $i < $string_length; $i++) {
$letter_space = 170/$string_length;
$initial = 15;
imagettftext($image, 24, rand(-15, 15), $initial + $i*$letter_space, rand(25, 45), $textcolors[rand(0, 1)], $fonts[array_rand($fonts)], $captcha_string[$i]);
}
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>
At first wordpress didn't find the font, but i manage to pass the error.
Then i call by shortcode the html. And i all i got is the alt and broken img. If i put directly the script in the function chrome tell me that my image contain errors. I did try to add utf8 encode and to pass the image without the header, none of that work.
public function CAPTCHA_shortcode_function() {
ob_start();
?>
<div class="elem-group">
<label for="captcha">Please Enter the Captcha Text</label>
<img src="CAPTCHA-generate-image.php" alt="CAPTCHA" class="captcha-image"><i class="fas fa-redo refresh-captcha"></i>
<br>
<input type="text" id="captcha" name="captcha_challenge" pattern="[A-Z]{6}">
</div>
<?php
$CAPTCHA = ob_get_clean();
return $CAPTCHA;
}
If you have any idea, something must be wrong ^^ Thanks a lot !
We did find a solution :
imagepng($captcha_image,"captcha_image.png");
$imgData = file_get_contents('captcha_image.png');
imagedestroy($captcha_image);
// $imgData = ob_get_clean();
return $imgData;
Then call it in the function like this
ob_start();
$imgData = $this->CAPTCHA_generate();
?>
<div id="CAPTCHA_box">
<label for="captcha">Entrez les </label><br>
<?php echo '<img class="captcha_image" src="data:image/png;base64,'.base64_encode($imgData).'" />'; ?>
<i class="fas fa-redo refresh_captcha"></i>
<br>
<input type="text" id="captcha" name="captcha_challenge" pattern="[A-Z]{6}">
</div>
<?php
$CAPTCHA = ob_get_clean();
return $CAPTCHA;

validate captcha when form submit using ajax and php

how can i validate if the user has enter the right captcha using ajax? and prevent the form submission if $_POST['captchainput'] != $_SESSION['code'].
this is the markup
<form action="captchaccept.php" method="POST" name="maincontact">
<input type="text" placeholder="Please enter the code" autocomplete="off" id="captchainput" name="captchainput">
<img src="captcha.php" id="captchaimage">
</form>
captcha.php
`
session_start();
$image_width = 135;
$image_height = 30;
$characters_on_image = 8;
$font = 'captchafont/acmesa.ttf';
$possible_letters = '23456789abcdfghjkmnpqrstvwxyz';
$random_dots = 10;
$random_lines = 30;
$captcha_text_color="0x142864";
$captcha_noice_color = "0x142864";
$code = '';
$i = 0;
while ($i < $characters_on_image) {
$code .= substr($possible_letters, mt_rand(0, strlen($possible_letters)-1), 1);
$i++;
}
$_SESSION['code'] = $code;
$font_size = 14;
$image = #imagecreate($image_width, $image_height);
$background_color = imagecolorallocate($image, 255, 255, 255);
$arr_text_color = hexrgb($captcha_text_color);
$text_color = imagecolorallocate($image, $arr_text_color['red'],
$arr_text_color['green'], $arr_text_color['blue']);
$arr_noice_color = hexrgb($captcha_noice_color);
$image_noise_color = imagecolorallocate($image, $arr_noice_color['red'],
$arr_noice_color['green'], $arr_noice_color['blue']);
for( $i=0; $i<$random_dots; $i++ ) {
imagefilledellipse($image, mt_rand(0,$image_width),
mt_rand(0,$image_height), 2, 3, $image_noise_color);
}
$textbox = imagettfbbox($font_size, 0, $font, $_SESSION['code']);
$x = ($image_width - $textbox[4])/2;
$y = ($image_height - $textbox[5])/2;
imagettftext($image, $font_size, 0, $x, $y, $text_color, $font , $_SESSION['code']);
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
function hexrgb ($hexstr) {
$int = hexdec($hexstr);
return array( "red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
}`
captchaaccept.php
`
session_start();
if(isset($_SESSION['code'])) {
if(empty($_POST['captchainput']) === false) {
if($_SESSION['code'] === $_POST['captchainput']) {
echo 'ok';
}
}
}`
can someone teach me how to use ajax validation for this captcha? or just show me an example , thanks in advance :)
Using jQuery you can do it like this:
(function($) {
$('#captchainput').on('submit', function(e) {
// Prevent the browser submitting the form
e.preventDefault();
// Put the form in variable form
var form = $(this);
// Do a AJAX post with the form data and check the response
$.post(form.attr('action'), form.serialize(), function(data) {
if(data === 'ok') {
// Captcha passed!
} else {
// Captcha failed!
}
});
});
})(jQuery);
Also in your code;
<form action="captchaccept.php" ... should be
<form action="captchaaccept.php" ... I think ;-)
Try this one also...
var posted_captcha = $( "#captchainput" ).val();
$.ajax({
url : 'captchaaccept.php',
data : 'captchainput=' + posted_captcha,
type : 'post',
success: function (res) {
if(res=='ok'){
alert('Validation pass');
}else{
alert('Validation fail');
}
}
});

Single Digit Captcha Match, PHP

I run a PTC website advertising websites for people. And i'm needing an easy to to lower or completely prevent bot usage.
After the advertisement counter is done counting down i would like a captcha to load.
But i don't want a captcha that you have to enter anything. Just a single mouse click.
If the captcha can be done in javascript that would be really great.
I'm looking for something sort of like this:
Counter:0 Select Matching Number: 7 [1] [0] [7] [2]
The user would have to click on the number in the box that matches the number.
Digits would be within 1-9.
Short of a full captcha you wont stop a determined bot.
A few ideas.
Allow 10 - 15 requests within 10 a minutes period, if it exceeds that, ask for captcha or block completely. Make sure this is IP based, because cookies/session wont work
Add some javascript to the form so that it cannot be posted without it. Most email collecting spam bots won't run javascript and give up. Generate a random string, store in $_SESSION on page request. Use javascript to add to the form post. if that string doesn't exist match on form post display a captcha.
Or use javascript to contstruct the form itself.
A determined scraper can get around most anything, but you just want to increase the cost of doing so.
I have made a CAPTCHA script. It's size, number of characters, and characters to choose from are customizable.
Here is captcha.php:
<?php
function generateCaptcha($num_digits, $challenge_num, $size, $chars, $incode = false) {
if(session_id() == '') session_start();
if(isset($_SESSION['captcha'])) unset($_SESSION['captcha']);
// You *must* type your own random salt here, *DO NOT* use this one.
$salt = 'H#(*h3^rh#(*E%h$W*WK#vMIv)%(D*(A&*W#A^D6#r4*I%u8tgsc#yejdi$d8dee';
$message = '';
if(isset($_POST['hash']) && isset($_POST['code'])) {
if(!empty($_POST['hash']) && !empty($_POST['code']) && !empty($_POST['correct_index'])) {
if(md5($_POST['hash'] . $_POST['code'] . $salt) == $_POST['correct_index']) {
$message = '<p>Correct!</p>';
} else {
$message = 'Incorrect code. Please try again.';
}
}
}
$code = '';
if($incode == false) {
for($i = 0; $i < $num_digits; $i++) {
$digit = substr($chars, floor(mt_rand(0, strlen($chars) - 1)), 1);
while(strpos($code, "$digit") !== false) {
$digit = substr($chars, floor(mt_rand(0, strlen($chars) - 1)), 1);
}
$code .= $digit;
}
} else {
for($i = 0; $i < $num_digits; $i++) {
$digit = substr($incode, floor(mt_rand(0, strlen($incode) - 1)), 1);
while(strpos($code, "$digit") !== false) {
$digit = substr($incode, floor(mt_rand(0, strlen($incode) - 1)), 1);
}
$code .= $digit;
}
}
$parts = str_split($code);
$width = $num_digits * $size;
$height = $size * 2;
$image = imagecreatetruecolor($width, $height);
$background = imagecolorallocate($image, floor(mt_rand(96, 255)), floor(mt_rand(96, 255)), floor(mt_rand(96, 255)));
imagefilledrectangle($image, 0, 0, $width, $height, $background);
$num_spots = floor(mt_rand($size * 2, $size * 15));
for($i = 0; $i < $num_spots; $i++) {
$color = imagecolorallocate($image, floor(mt_rand(30, 255)), floor(mt_rand(30, 255)), floor(mt_rand(30, 255)));
$x = floor(mt_rand(0, $width));
$y = floor(mt_rand(0, $height));
$ellipse_width = floor(mt_rand(0, $size / 2));
$ellipse_height = floor(mt_rand(0, $size / 2));
imagefilledellipse($image, $x, $y, $ellipse_width, $ellipse_height, $color);
$x1 = floor(mt_rand(0, $width));
$y1 = floor(mt_rand(0, $height));
$x2 = floor(mt_rand(0, $width));
$y2 = floor(mt_rand(0, $height));
imageline($image, $x1, $y1, $x2, $y2, $color);
}
$num_dots = floor(mt_rand($size * 50, $size * 80));
for($i = 0; $i < $num_dots; $i++) {
$color = imagecolorallocate($image, floor(mt_rand(30, 255)), floor(mt_rand(30, 255)), floor(mt_rand(30, 255)));
$x = floor(mt_rand(0, $width));
$y = floor(mt_rand(0, $height));
imagesetpixel($image, $x, $y, $color);
}
for($i = 0; $i < count($parts); $i++) {
$color = imagecolorallocate($image, floor(mt_rand(0, 150)), floor(mt_rand(0, 150)), floor(mt_rand(0, 150)));
$x = floor(mt_rand($size * 0.9, $size * 1.1));
$y = floor(mt_rand($size, $size * 2));
imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x, $y, $color, 'Justus-Bold.ttf', $parts[$i]);
imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x + floor(mt_rand(1, 7)), $y, $color, 'Justus-Bold.ttf', $parts[$i]);
imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x + floor(mt_rand(1, 7)), $y, $color, 'Justus-Bold.ttf', $parts[$i]);
imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x + floor(mt_rand(1, 7)), $y, $color, 'Justus-Bold.ttf', $parts[$i]);
}
$white = imagecolorallocate($image, 255, 255, 255);
$filename = md5(time() . $_SERVER['REMOTE_ADDR'] . mt_rand(0, 1000)) . '.png';
imagepng($image, $filename);
imagedestroy($image);
$file = file_get_contents($filename);
$imgsize = getimagesize($filename);
unlink($filename);
$captcha = 'data:' . $imgsize['mime'] . ';base64,' . base64_encode($file);
$challenge = array('captcha' => '', 'code' => null, 'size' => 0, 'digits' => 0);
if($incode == false) {
$challenge = generateCaptcha($challenge_num, 0, $size, $chars, $code);
}
$hash = md5($challenge['code'] . $salt);
$correct_index = array();
for($i = 0; $i < strlen($challenge['code']); $i++) {
$correct_index[] = strpos($code, substr($challenge['code'], $i, 1));
}
$result = array(
'captcha' => $captcha,
'challenge' => array($challenge['captcha'], $challenge['size'], $challenge['digits']),
'size' => array($imgsize[0], $imgsize[1]),
'hash' => $hash,
'code' => $code,
'message' => $message,
'width' => $size,
'digits' => $num_digits,
'correct_index' => md5($hash . implode('', $correct_index) . $salt)
);
return $result;
}
?>
...and here is captcha.html:
<!DOCTYPE HTML>
<!--
<?php
include 'captcha.php';
$captcha = generateCaptcha(4, 2, 100, '0123456789');
?>
-->
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>Click-captcha test</title>
<style type="text/css">
#challenge, #captcha-img {
margin: 10px
}
#captcha-img {
overflow: hidden
}
.captcha-digit {
display: block;
float: left;
width: <?php echo $captcha['width']; ?>px;
height: 100%;
cursor: pointer
}
.captcha-digit-selected {
background: #ccc;
opacity: .75;
filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#f2cccccc', EndColorStr='#f2cccccc')
}
</style>
<script type="text/javascript">
var captchaLinks = [];
var digits = [];
var num_digits = <?php echo $captcha['challenge'][2]; ?> - 1;
addEvent(window, 'load', init);
function init() {
captchaLinks = ['<?php
$digits = array();
for($i = 'digit0'; $i < 'digit' . $captcha['digits']; $i++) {
$digits[] = $i;
}
echo implode("', '", $digits);
?>'];
for(var i = 0; i < captchaLinks.length; i++) {
//for(var link in captchaLinks) {
addEvent(document.getElementById(captchaLinks[i]), 'click', newCaptchaDigit);
}
}
function newCaptchaDigit(e) {
if(e.target.className == 'captcha-digit captcha-digit-selected') {
digits.splice(digits.indexOf(e.target.id.substr(-1, 1)), 1);
e.target.className = 'captcha-digit';
} else if(digits.length <= num_digits) {
digits.splice(num_digits, digits.length - num_digits, e.target.id.substr(-1, 1));
e.target.className = 'captcha-digit captcha-digit-selected';
}
document.getElementById('code').value = digits.join('');
}
function addEvent(elem, event, handler) {
if(elem !== null & typeof elem !== 'undefined') {
if(elem.addEventListener) {
elem.addEventListener(event, handler, false);
} else if(elem.attachEvent) {
elem.attachEvent('on' + event, handler);
} else if(elem['on' + event]) {
elem['on' + event] = handler;
}
}
}
</script>
</head>
<body>
<div>
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
<div id="captcha">
<div><?php echo $captcha['message']; ?></div>
<div>Click the following number sequence:
<div id="challenge" style="width: <?php echo $captcha['challenge'][1][0]; ?>px; height: <?php echo $captcha['challenge'][1][1]; ?>px; background-image: url('<?php echo $captcha['challenge'][0]; ?>')"></div>
</div>
<div id="captcha-img" style="width: <?php echo $captcha['size'][0]; ?>px; height: <?php echo $captcha['size'][1]; ?>px; background-image: url('<?php echo $captcha['captcha']; ?>')">
<?php for($i = 'digit0'; $i < 'digit' . $captcha['digits']; $i++) { ?>
<a class="captcha-digit" id="<?php echo $i; ?>"></a>
<?php } ?>
</div>
</div>
<input type="hidden" name="hash" value="<?php echo $captcha['hash']; ?>" />
<input type="hidden" name="correct_index" value="<?php echo $captcha['correct_index']; ?>" />
<input type="hidden" name="code" id="code" value="" />
<input type="submit" value="Submit" />
</form>
</div>
</body>
</html>
Hopefully you will able to see what is going on, but I will explain it here. :-)
The function is called generateCaptcha, and it accepts the parameters $num_digits, $challenge_num, $size, $chars, $incode = false.
$num_digits: number of characters to put in the CAPTCHA
$challenge_num: number of characters to put into the challenge
$size: size of the CAPTCHA
$chars: what characters to include (e.g. for numbers: '0123456789')
$incode: this is just so the script can tell if it has been called by itself to generate the challenge or not. Don't set it.
So to create a CAPTCHA image with 4 characters, a 1 character challenge (like your question), size 30, and only with digits, use this code:
<?php
include 'captcha.php';
$captcha = generateCaptcha(4, 1, 30, '0123456789');
?>
Then the variable $captcha will end up something like this:
array(9) {
["captcha"]=>
string(118058) "data:image/png;base64,iVBORw0KG...kSuQmCC"
["challenge"]=>
array(3) {
[0]=>
string(76266) "data:image/png;base64,iVBORw0KG...kJggg=="
[1]=>
array(2) {
[0]=>
int(200)
[1]=>
int(200)
}
[2]=>
int(2)
}
["size"]=>
array(2) {
[0]=>
int(400)
[1]=>
int(200)
}
["hash"]=>
string(32) "81bc501400b8da366e70b26007cb2323"
["code"]=>
string(4) "4817"
["message"]=>
string(0) ""
["width"]=>
int(100)
["digits"]=>
int(4)
["correct_index"]=>
string(32) "17ae615be69c757505dc7f69fce2afb1"
}
If you need any more information, please ask in a comment.

How can I replace one color with another in a png 24 alpha transparent image with GD

I have tried:
$index = imagecolorresolve ( $im, 0,0,0 ); // get black
imagecolorset($im, $index, 255, 0, 255); // SET NEW COLOR
This seems to work with png 8 but not 24, and if I do it with 8 it turns out all weird because of the anti-aliasing.
Here is the full test code I'm using. (this is just test code, so be gentle).
function LoadPNG($imgname, $color = false)
{
$im = #imagecreatefrompng($imgname);
imagealphablending($im, false);
if($color) {
$index = imagecolorresolve ( $im, 0,0,0 ); // get black
imagecolorset($im, $index, 255, 0, 255); // SET NEW COLOR
}
imageAlphaBlending($im, true);
imageSaveAlpha($im, true);
return $im;
}
header('Content-Type: image/png');
$img = LoadPNG("head.png", "red");
imagepng($img);
imagedestroy($img);
Based on the solution of inti, i made a script that works:
$imgname = "yourimage.png";
$im = imagecreatefrompng($imgname);
imagealphablending($im, false);
for ($x = imagesx($im); $x--;) {
for ($y = imagesy($im); $y--;) {
$rgb = imagecolorat($im, $x, $y);
$c = imagecolorsforindex($im, $rgb);
if ($c['red'] < 40 && $c['green'] < 40 && $c['blue'] < 40) { // dark colors
// here we use the new color, but the original alpha channel
$colorB = imagecolorallocatealpha($im, 255, 0, 255, $c['alpha']);
imagesetpixel($im, $x, $y, $colorB);
}
}
}
imageAlphaBlending($im, true);
imageSaveAlpha($im, true);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
I'd like a way to optimize it, because it is quite slow
You can try the following:
cycle all points
get the color of that point
if it matches your colorA, set that pixel to the desired colorB
Code:
for ($x=imagesx($im); $x--; ) {
for ($y=imagesy($im); $y--; ) {
$c = imagecolorat($im, $x, $y);
if ($c[0] == 0 && $c[1] == 0 && $c[2] == 0) {
// here we use the new color, but the original alpha channel
$colorB = imagecolorallocatealpha($im, 255, 0, 255, $c[3]);
imagesetpixel($im, $x, $y, $colorB);
}
}
}
Hope this helps!
this function will replace either 1 or all colors for 1 new color, maintaining transparency levels (otherwise borders will probably look awful, if PARTIAL transparency was used to draw borders).
COMPLETE ANSWER TO SIMILAR POST
<?php
function colorizeKeepAplhaChannnel( $inputFilePathIn, $targetRedIn, $targetGreenIn, $targetBlueIn, $outputFilePathIn ) {
$im_src = imagecreatefrompng( $inputFilePathIn );
$im_dst = imagecreatefrompng( $inputFilePathIn );
$width = imagesx($im_src);
$height = imagesy($im_src);
// Note this: FILL IMAGE WITH TRANSPARENT BG
imagefill($im_dst, 0, 0, IMG_COLOR_TRANSPARENT);
imagesavealpha($im_dst,true);
imagealphablending($im_dst, true);
$flagOK = 1;
for( $x=0; $x<$width; $x++ ) {
for( $y=0; $y<$height; $y++ ) {
$rgb = imagecolorat( $im_src, $x, $y );
$colorOldRGB = imagecolorsforindex($im_src, $rgb);
$alpha = $colorOldRGB["alpha"];
$colorNew = imagecolorallocatealpha($im_src, $targetRedIn, $targetGreenIn, $targetBlueIn, $alpha);
$flagFoundColor = true;
// uncomment next 3 lines to substitute only 1 color (in this case, BLACK/greys)
/*
$colorOld = imagecolorallocatealpha($im_src, $colorOldRGB["red"], $colorOldRGB["green"], $colorOldRGB["blue"], 0); // original color WITHOUT alpha channel
$color2Change = imagecolorallocatealpha($im_src, 0, 0, 0, 0); // opaque BLACK - change to desired color
$flagFoundColor = ($color2Change == $colorOld);
*/
if ( false === $colorNew ) {
//echo( "FALSE COLOR:$colorNew alpha:$alpha<br/>" );
$flagOK = 0;
} else if ($flagFoundColor) {
imagesetpixel( $im_dst, $x, $y, $colorNew );
//echo "x:$x y:$y col=$colorNew alpha:$alpha<br/>";
}
}
}
$flagOK2 = imagepng($im_dst, $outputFilePathIn);
if ($flagOK && $flagOK2) {
echo ("<strong>Congratulations, your conversion was successful </strong><br/>new file $outputFilePathIn<br/>");
} else if ($flagOK2 && !$flagOK) {
echo ("<strong>ERROR, your conversion was UNsuccessful</strong><br/>Please verify if your PNG is truecolor<br/>input file $inputFilePathIn<br/>");
} else if (!$flagOK2 && $flagOK) {
$dirNameOutput = dirname($outputFilePathIn)."/";
echo ("<strong>ERROR, your conversion was successful, but could not save file</strong><br/>Please verify that you have PERMISSION to save to directory $dirName <br/>input file $inputFilePathIn<br/>");
} else {
$dirNameOutput = dirname($outputFilePathIn)."/";
echo ("<strong>ERROR, your conversion was UNsuccessful AND could not save file</strong><br/>Please verify if your PNG is truecolor<br/>Please verify that you have PERMISSION to save to directory $dirName <br/>input file $inputFilePathIn<br/>");
}
echo ("TargetName:$outputFilePathIn wid:$width height:$height CONVERTED:|$flagOK| SAVED:|$flagOK2|<br/>");
imagedestroy($im_dst);
imagedestroy($im_src);
}
$targetRed = 255;
$targetGreen = 255;
$targetBlue = 0;
//$inputFileName = 'frameSquareBlack_88x110.png';
$inputFileName = 'testMe.png';
$dirName = "../img/profilePics/";
$nameTemp = basename($inputFileName, ".png");
$outputFileName = $nameTemp."_$targetRed"."_$targetGreen"."_$targetBlue.png";
$inputFilePath = $dirName.$inputFileName;
$outputFilePath = $dirName.$outputFileName;
//echo "inputFileName:$inputFilePath<br>outputName:$outputFilePath<br>";
colorizeKeepAplhaChannnel( $inputFilePath, $targetRed, $targetGreen, $targetBlue, $outputFilePath);
?>
<br/><br/>
Original <br/>
<img src="<?php echo $inputFilePath; ?>">
<br /><br />Colorized<br/>
<img src="<?php echo $outputFilePath; ?>">
<br />
A good way to doing it is using paintOpaqueImage(), which also permit using color tolerance
$targetColor = "#0074AD";
$fill = "#0074AA";
$tolerance = 30000;
$im = new Imagick( "yourimage.png");
if ($im->paintOpaqueImage ( $targetColor , $fill , $tolerance) ){
$im->writeImage("yourimage.png");
}
You can see the tolenrance doc in http://www.imagemagick.org/script/command-line-options.php#fuzz
This function work like a charm :
public function ImageToBlackAndWhite($im) {
for ($x = imagesx($im); $x--;) {
for ($y = imagesy($im); $y--;) {
$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$gray = ($r + $g + $b) / 3;
if ($gray < 0xFF) {
imagesetpixel($im, $x, $y, 0xFFFFFF);
}else
imagesetpixel($im, $x, $y, 0x000000);
}
}
imagefilter($im, IMG_FILTER_NEGATE);
}

Creating IMage from Text in PHP - how can I make multiline?

I have a script that generates images from text using PHP. It's working fine except that I would like it to generate multiline text as well with differing colors. How can it be done using PHP, GD and Freetype? Below is the code I use to generate single line text images.
$textval = 'This is some text to be an image';
$textcolor = '666666';
$font="arial.ttf";
$size = 9;
$padding= 1;
$bgcolor= "ffffff";
$transparent = 0;
$antialias = 0;
$fontfile = $fontpath.$font;
$box= imageftbbox( $size, 0, $fontfile, $textval, array());
$boxwidth= $box[4];
$boxheight= abs($box[3]) + abs($box[5]);
$width= $boxwidth + ($padding*2) + 1;
$height= $boxheight + ($padding) + 0;
$textx= $padding;
$texty= ($boxheight - abs($box[3])) + $padding;
// create the image
$png= imagecreate($width, $height);
$color = str_replace("#","",$bgcolor);
$red = hexdec(substr($bgcolor,0,2));
$green = hexdec(substr($bgcolor,2,2));
$blue = hexdec(substr($bgcolor,4,2));
$bg = imagecolorallocate($png, $red, $green, $blue);
$color = str_replace("#","",$textcolor);
$red = hexdec(substr($textcolor,0,2));
$green = hexdec(substr($textcolor,2,2));
$blue = hexdec(substr($textcolor,4,2));
$tx = imagecolorallocate($png, $red, $green, $blue);
imagettftext( $png, $size, 0, $textx, $texty, $tx, $fontfile, $textval );
header("content-type: image/jpeg");
imagejpeg($png);
imagedestroy($png);
exit;
Add this function to wrap the text before it goes into your function.
function wrap($fontSize, $angle, $fontFace, $string, $width){
$ret = "";
$arr = explode(' ', $string);
foreach ( $arr as $word ){
$teststring = $ret.' '.$word;
$testbox = imagettfbbox($fontSize, $angle, $fontFace, $teststring);
if ( $testbox[2] > $width ){
$ret.=($ret==""?"":"\n").$word;
} else {
$ret.=($ret==""?"":' ').$word;
}
}
return $ret;
}
Source: http://www.php.net/imagettftext

Categories