Cómo convertir imágenes a ASCII en PHP

¿Alguna vez ha querido enviar, mostrar o utilizar versiones coloreadas en ASCII de imágenes reales? Pues bien, resulta que esto no es algo muy difícil de lograr con PHP. En este tutorial, vamos a crear una simple clase que tenga la habilidad de convertir todo tipo de direcciones URL a imágenes jpg/gif/png en ASCII. También con la clase podremos mostrar dicho ASCII en las dimensiones especificadas por el usuario (vcambiaremos el tamaño de la imagen a las dimensiones especificadas por el usuario antes de la conversión a ASCII). Por otra parte, vamos a desarrollar una sencilla interfaz web donde los usuarios puedan introducir las URLs de las imágenes y las dimensiones que quieran. A comtinuación se mostrará el ASCII, así como un código HTML para embeber la imagen ASCII en otro sitio web.

Convertir la imagen a ASCII y redimensión

Para empezar, vamos a esconder los errores y a inicializar nuestra clase:

<?php

ini_set("display_errors", "off");

//accepts a path to an image, and the desired width/height of the ASCII

class ImageToAscii {

Inicializamos la clase por lo menos con una ruta a una imagen y, opcionalmente, las dimensiones de la imagen resultante. En nuestro método constructor, fijamos las propiedades adecuadas y nos preparamos para cambiar el tamaño de la imagen. Por defecto, se mostrará al usuario un ASCII de 90 × 40. Como he dicho antes, los usuarios podrán cambiar dicho tamaño hasta un límite de 600 × 600.

private $file = null;

private $img = null;

private $error = null;

public function __construct($file, $resizeX,$resizeY) {

$this->file = $file;

$this->resizeX = $resizeX;

$this->resizeY = $resizeY;

if (!($this->resizeX && $this->resizeY && is_numeric($this->resizeX) && is_numeric($this->resizeY) && (int)$this->resizeX > 0 && (int)$this->resizeY > 0 && (int)$this->resizeX < 600 && (int)$this->resizeY < 600)) {

$this->resizeX = 90;

$this->resizeY = 40;

}

}

El método getImage crea una imagen en función de la extensión de la imagen remota la cual ha sido proporcionada al constructor de la clase, o muestra un error si algo ha salido mal (o la extensión del imagen no está soportada o ha habido problemas al crear la imagen).

private function getImage() {

$ext = array_pop(explode(".", $this->file));

if ($ext === "gif") {

$this->img = imagecreatefromgif($this->file);

}

else if ($ext === "png") {

$this->img = imagecreatefrompng($this->file);

}

else if ($ext === "jpg" || $ext === "jpeg") {

$this->img = imagecreatefromjpeg($this->file);

}

else {

$this->error = "Unsupported file/image type :(";

}

if (!$this->img) {

$this->error = "We cannot read this image yet :(";

}

}

El método convert será llamado cuando queramos obtener el ASCII sólo si la imagen está disponible y si no ha habido ningún error.

public function convert() {

$this->getImage();

return $this->error ? $this->error : $this->toAscii();

}

El método actual (toASCII) convierte la imagen a ASCII cogiendo sus dimensiones y definiéndolas en las variables. A continuación, se crea una nueva imagen de las dimensiones deseadas o sino de las dimensiones por defecto con la ayuda de imagecreatetruecolor ($w, $h). Después se cambia el tamaño de la imagen original en la nueva imagen con la ayuda de imagecopyresampled, y se anula la imagen original por la nueva. Después se cambian las variables de anchura y altura para atender a las nuevas dimensiones.

private function toAscii() {

$imgSize = getimagesize($this->file);

$width = $imgSize[0];

$height = $imgSize[1];

$newImg = imagecreatetruecolor($this->resizeX, $this->resizeY);

imagecopyresampled($newImg, $this->img, 0, 0, 0,0, $this->resizeX, $this->resizeY, $width,$height);

$this->img = $newImg;

$width = $this->resizeX;

$height = $this->resizeY;

Por último, creamos un tag pre, iteramos sobre cada píxel de la imagen y creamos una etiqueta span coloreada después del píxel original con # como contenido. Después de cada línea de imagen, se añade la etiqueta br para añadir una nueva línea. Entonces, devolvemos la salida al usuario

$out = "<pre width='$width' height='$height'>";

for ($h = 0; $h < $height;$h++ ) {

for ($w = 0; $w < $width;$w++) {

$rgb = imagecolorat($this->img, $w,$h);

$r = ($rgb >> 16) & 0xFF;

$g = ($rgb >> 8) & 0xFF;

$b = $rgb & 0xFF;

$out .= "<span style='color:rgb($r,$g,$b)'>#</span>";

}

$out .="<br>";

 

}

 

$out .= "</pre>";

return $out;

Creando una interfaz

No vamos a repetir otra vez el desarrollo de cómo convertir una imagen a ASCII, sino que nos centraremos en crear una sencilla interfaz para el usuario. Si el usuario no ha enviado el formulario todavía, solo mostramos personalizado con Bootstrap. Mostramos un input para las direcciones URL y dos inputs numéricos. Fíjate en el tag meta viewport en el head ya que indica si el sitio es responsive o no.

<?php

if (!isset($_REQUEST['img'])): ?>

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Kewl Image to Ascii Converter</title>

<meta name='viewport' content='initial-scale=1,width=device-width'>

<link rel="stylesheet" href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css'>

<link rel="stylesheet" href='https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/superhero/bootstrap.min.css'>

</head>

<body class="container-fluid col-md-6 col-md-offset-3 col-xs-12 col-sm-10 col-ms-offset-1">

<form >

<h1 class='text-center'>Convert an arbitrary online image to colored ASCII</h1>

<label for="img">URL to image</label>

<input id="img" type="url" class='form-control' name="img">

<div class='col-md-6'>

<label for='resizeX'>Change Image Width (ASCII can be max 600px)</label>

<input value='90' class='form-control' type='number' id='resizeX' name='resizeX' placeholder="Desired Image Width"> 

</div>

<div class='col-md-6'>

<label for='resizeY'>Change Image Height (ASCII can be max 600px)</label>

<input value='40' class='form-control' type='number' id='resizeY' name='resizeY' placeholder="Desired Image Height">

</div>

<button type='submit' class='btn btn-lg btn-success'>Convert to ASCII</button>

</form>

</body>

</html>

Por último, si se envía el formulario, vuelve a mostrar el formulario original y también la salida ASCII con el código HTML dentro de un textarea para que los usuarios pueden copiarlo y utilizarlo en su propio sitio web o blog. También pueden autocompletarel formulario con la última consulta enviada por el usuario.

<?php

    else:

$resizeX = isset($_REQUEST['resizeX']) ? $_REQUEST['resizeX'] : null;

$resizeY = isset($_REQUEST['resizeY']) ? $_REQUEST['resizeY'] : null;

require_once("imageToAscii.php");

$ascii = new ImageToAscii($_REQUEST['img'],$resizeX, $resizeY);

$ascii = $ascii->convert();

?>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Kewl Image to Ascii Converter</title>

<meta name='viewport' content='initial-scale=1,width=device-width'>

<link rel="stylesheet" href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css'>

<link rel="stylesheet" href='https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/superhero/bootstrap.min.css'>

</head>

<body class="container-fluid col-md-6 col-md-offset-3 col-xs-12 col-sm-10 col-ms-offset-1">

<form>

<h1 class='text-center'>Convert an arbitrary online image to colored ASCII</h1>

<label for="img">URL to image</label>

<input value="<?php echo isset($_REQUEST['img']) ? htmlspecialchars($_REQUEST['img']) : ""; ?>"  placeholder="https://upload.wikimedia.org/wikipedia/en/7/77/EricCartman.png" id="img" type="url" class='form-control' name="img">

<div class='col-md-6'>

<label for='resizeX'>Change Image Width (ASCII can be max 600px)</label>

<input value='<?php echo isset($_REQUEST['resizeX']) ? htmlspecialchars($_REQUEST['resizeX']) : 90;?>' class='form-control' type='number' id='resizeX' name='resizeX' placeholder="Desired Image Width">

</div>

<div class='col-md-6'>

<label for='resizeY'>Change Image Heig (ASCII can be max 600px)</label>

<input value='<?php echo isset($_REQUEST['resizeY']) ? htmlspecialchars($_REQUEST['resizeY']) : 40;?>' class='form-control' type='number' id='resizeY' name='resizeY' placeholder="Desired Image Height">

</div>

<button type='submit' class='btn btn-lg btn-success'>Convert to ASCII</button>

</form>

<?php echo  $ascii;?>

<label for="markup">HTML Code (i.e, to add the ASCII to a page)</label>

<textarea class='form-control' id="markup"><?php echo htmlspecialchars($ascii);?></textarea>

<?php

    endif;

?>

Fuente: phpgang.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP