<?php if( !isset($_GET["k"]) || preg_match( '/^c\.[0-9]+$/', $_GET["k"] ) ){ header("Content-Type: text/plain"); echo "Fuck you"; die(); } header("Content-Type: image/jpeg"); $grid = apcu_fetch($_GET["k"]); if( $grid === false || $grid[3] === true // has already been generated ){ http_response_code(304); // not modified die(); } header("Last-Modified: Thu, 01 Oct 1970 00:00:00 GMT"); // only generate one captcha with this config apcu_store( $_GET["k"], [ $grid[0], $grid[1], $grid[2], true // has captcha been generated? ], 120 // we give user another 2 minutes to solve ); // generate image if(random_int(0,1) === 0){ $theme = [ "bg" => "#ebdbb2", "fg" => "#1d2021" ]; }else{ $theme = [ "bg" => "#1d2021", "fg" => "#ebdbb2" ]; } $im = new Imagick(); $im->newImage(400, 400, $theme["bg"]); $im->setImageBackgroundColor($theme["bg"]); $im->setImageFormat("jpg"); $noise = [ imagick::NOISE_GAUSSIAN, imagick::NOISE_LAPLACIAN ]; $distort = [ imagick::DISTORTION_AFFINE, imagick::DISTORTION_SHEPARDS ]; $i = 0; for($y=0; $y<4; $y++){ for($x=0; $x<4; $x++){ $tmp = new Imagick("./data/captcha/" . $grid[0][$i][0] . "/" . random_int(1, $grid[0][$i][1]) . ".png"); // convert transparency correctly $tmp->setImageBackgroundColor("black"); $tmp->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE); // distort $tmp $tmp->distortImage( $distort[random_int(0,1)], [ 0, 0, random_int(-15, 15), random_int(-15, 15), 100, 0, random_int(80, 120), random_int(-15, 15), 100, 100, random_int(80, 120), random_int(80, 120), 0, 100, random_int(-15, 15), random_int(80, 120) ], false ); // append image $im->compositeImage($tmp->getImage(), Imagick::COMPOSITE_DEFAULT, $x * 100, $y * 100); $i++; } } // add noise $im->addNoiseImage($noise[random_int(0, 1)]); // expand top of image $im->setImageGravity(Imagick::GRAVITY_SOUTH); $im->chopImage(0, -27, 400, 400); $im->extentImage(0, 0, 0, -27); // add text $draw = new ImagickDraw(); $draw->setFontSize(20); $draw->setFillColor($theme["fg"]); //$draw->setTextAntialias(false); $draw->setFont("./data/captcha/font.ttf"); $text = "Pick " . $grid[1] . " images of " . str_replace("_", " ", $grid[2]); $pos = 200 - ($im->queryFontMetrics($draw, $text)["textWidth"] / 2); for($i=0; $i<strlen($text); $i++){ $im->annotateImage( $draw, $pos, 20, random_int(-15, 15), $text[$i] ); $pos += $im->queryFontMetrics($draw, $text[$i])["textWidth"]; } $im->setFormat("jpeg"); $im->setImageCompressionQuality(90); $im->setImageCompression(Imagick::COMPRESSION_JPEG2000); echo $im->getImageBlob();