Ver índice
Imágenes en tablas

        Ocultar índice  

   Índice de contenidos
   Instalación en Windows
   Instalación en Ubuntu
   Servidores seguros
   Páginas dinámicas
   Sintaxis básica
   Operaciones
   Arrays
   Formatos de presentación
   Operadores
   Bucles
   Extraer y ord. información
   Funciones
   Ficheros externos
   Imágenes dinámicas
   Gestión de directorios
   Cookies y sesiones
   Clases y objetos
   Ficheros en formato PDF
   Bases de datos MySQL
   PHP y XML
   PDO - Bases SQLite / MySQL
   MySQL a traves de misqli
   Algo de JavaScript y AJAX


Imágenes en tablas

Peculiaridades de las tablas

Las tablas que han de contener imágenes deben tener campos del tipo BLOB, MEDIUMBLOB o LONGBLOB, (recuerda sus tipos) pudiendo elegir aquel de ellos que más se adecue al tamaño, en bytes, de las imágenes que se desean guardar en la tabla.

En el ejemplo hemos incluido un campo BLOB para incluir la imagen, insertando también campos para recoger su nombre, su tamaño (en bytes), su formato (el tipo de fichero transferido) así como un campo autoincremental.

<?php
#el nombre de la tabla
$base="ejemplos";
#definimos otra variable con el NOMBRE QUE QUEREMOS DAR A LA TABLA
$tabla="fotos";
# establecemos la conexión con el servidor
$conexion=mysql_connect ("localhost","pepe","pepa");
#Seleccionamos la BASE DE DATOS en la que PRETENDEMOS CREAR LA TABLA
mysql_select_db ($base, $conexion);

$crear="CREATE TABLE IF NOT EXISTS $tabla (";
$crear.="num_ident INT(10) unsigned NOT NULL AUTO_INCREMENT,";
$crear.="imagen BLOB NOT NULL, ";
$crear.="nombre VARCHAR(255) NOT NULL DEFAULT '',";
$crear.="tamano VARCHAR(15) NOT NULL DEFAULT  '',";
$crear.="formato VARCHAR(10) NOT NULL DEFAULT  '',";
$crear.="PRIMARY KEY (num_ident))type=MyISAM";

#Creamos la cadena, comprobamos si esa instrucción devuelve
# VERDADERO o FALSO
# y dependiendo de ellos insertamos el mensaje de exito o fracaso

if(mysql_db_query ($base,$crear ,$conexion)) {
echo "<h2> Tabla $tabla creada con EXITO </h2><br>";
    }else{
echo "<h2> La tabla $tabla NO HA PODIDO CREARSE</h2><br>";
};

# cerramos la conexión... y listo...

        mysql_close($conexion);
?>

Aquí tiene el código fuente que te permitiría crear la tabla fotos e insertar automáticamente algunas imágenes de ejemplo.

Ejemplo de transferencia de imagen

Transferencia de la imagen

El formulario para realizar la transferencia de la imagen no tiene particularidades. Es un formulario habitual para transferencia de ficheros. Lo único reseñable sería incluir un campo oculto en el que pudiera especificarse una restricción en cuanto al tamaño máximo permitido para cada imagen y que debe estar acorde con el tipo de campo utilizado en la tabla.

<FORM ENCTYPE="multipart/form-data" ACTION="ejemplo211.php" METHOD="post">

<INPUT type="hidden" name="lim_tamano" value="65000">
<p><b>Selecciona la imagen a transferir<b><br>
<INPUT type="file" name="foto"><br>
<p><b>Título la imagen<b><br>
<INPUT type="text" name="titulo"><br></p>
<p><INPUT type="submit" name="enviar" value="Aceptar"></p>
</FORM>
Ejemplo de transferencia de imagen

Comprobación del tipo de imagen

Al transferir imágenes jpg ó png el type MIME que recibía el servidor es distinto según el navegador que se utilice para hacer la transferencia.

Aquí debajo, en el código fuente del script que actualiza la base de datos, tienes los nombres de esos tipos asociados a los navegadores más usuales.

<?php
$foto_name= $_FILES['foto']['name'];
$foto_size= $_FILES['foto']['size'];
$foto_type=  $_FILES['foto']['type'];
$foto_temporal= $_FILES['foto']['tmp_name'];
$lim_tamano= $_POST['lim_tamano'];
$foto_titulo= $_POST['titulo'];
/* limitamos los formatos de imagen admitidos a:
    png  que segun del navegador que ulicemos puede ser:
   en IE image/x-png  en Firefox y Mozilla image/png
   jpg que puede tener como tipo
   en IE image/pjpeg  en Firefox y Mozilla image/jpeg
   gif que tiene como tipo image/gif en todos los navegadores
    Mira los comentarios al margen sobre la variable $extensión */
if ($foto_type=="image/x-png" OR $foto_type=="image/png"){
 $extension="image/png";
 }
if ($foto_type=="image/pjpeg" OR $foto_type=="image/jpeg"){
 $extension="image/jpeg";
 }
if ($foto_type=="image/gif" OR $foto_type=="image/gif"){
 $extension="image/gif";
 }
# condicionamos la inserción a que la foto tenga nombre,
# un tamaño distinto de cero y menor de límite establecido
# en el formulario y que la variable extensión sea no nula

if ($foto_name != "" AND $foto_size != 0
                           AND $foto_titulo !='' AND
                        $foto_size<=$lim_tamano AND $extension !=''){
/*reconversion de la imagen para meter en la tabla
 abrimos el fichero temporal en modo
 lectura "r" binaria"b"*/
$f1= fopen($foto_temporal,"rb");
#leemos el fichero completo limitando
#  la lectura al tamaño de fichero
$foto_reconvertida = fread($f1, $foto_size);
#anteponemos \ a las comillas que pudiera contener el fichero
# para evitar que sean interpretadas como final de cadena
$foto_reconvertida=addslashes($foto_reconvertida);
# abrimos la base de datos y escribimos las intrucciones de inserción
# en el campo BLOB insertaremos la foto_reconvertida
$base="ejemplos";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
$meter="INSERT INTO ".$tabla;
$meter .=" (num_ident, imagen, nombre, tamano, formato) ";
$meter .=" VALUES('','$foto_reconvertida','$foto_titulo',";
$meter .= "$foto_size, '$extension')";
    if (@mysql_query($meter,$conexion)){
        print "Foto guardada en la tabla";
        }else{
        print "Ha habido un error al guardar la foto";
    }
}else{
    echo "<h2>No ha podido transferirse el fichero</h2>";
 }
 mysql_close();
?>

Hay otro aspecto a tener en cuenta. Esa discriminación de tipos se plantea únicamente cuando Apache recibe una transferencia. Cuando se visualiza un contenido las cabeceras tipo de contenido (header("content-type: xx")) pueden ser las mismas para todos los navegadores. Esa es la razón por la que a la hora de incluir el formato en la tabla utilizamos image/jpg, image/gif o image/png.

¿Cómo guardamos la imagen?

La información recibida a través del formulario requiere un ligero retoque antes de incluirla en le campo BLOB de la tabla. Esa reconversión requiere abrir la imagen en modo binario (rb) -parece que solo en el caso de Windows– leer el fichero completo y añadirle \ antes de las comillas mediante addslashes.

Una vez hecho el retoque ya puede guardarse sin más problema.

PNG con transparencias en Internet Explorer

Internet Explorer no permite visualizar de forma automática las transparencias de las imágenes con formato png. Existen en la red algunos recursos que permiten solventar ese problema. Hemos elegido uno de ellos –pngfix.js- que puedes ver en este enlace.

Se trata de un fichero JavaScript que basta incluir en la cabecera HMTL de la página de la forma que ves en el ejemplo de la parte derecha. Cuando un navegador IE es detectado se ejecuta una función contenida en ese fichero que analiza la página, busca imágenes con extensión png y les aplica la transparencia adecuada.

Por esa razón, es probable que inicialmente (al cargar la página) se visualice la imagen opaca y que, posteriormente, adquiera la transparencia.

Visualización de imágenes

La lectura de una imagen utiliza solo dos instrucciones. Incluir la cabecera Header en el que se indica el tipo de contenido (el famoso nombre MIME de la imagen) y luego imprimir el contenido del campo. Pero (por aquello de que header debe ir incluida en el script antes que cualquier otra salida) si pretendemos incluir en una página algo más que una imagen tendremos que invocar esas dos funciones, de forma independiente, para cada una de ellas.

Por esa razón, en el ejemplo que tienes al margen, al desarrollar el ejemplo que permite visualizar todas las imágenes de la tabla hemos tenido que incluir un script que va leyendo la tabla que contiene las imágenes para extraer los campos informativos y a la hora de ver la imagen hemos de recurrir a la misma técnica que se utilizaba para ver las imágenes dinámicas. Es decir, poner una etiqueta de imagen de las de HTML pero -en vez de escribir el nombre de la imagen- poniendo incluyendo como nombre el del script que las visualiza y pasándole el número (valor del campo autoincremental) de la imagen que pretendí visualizar.

Script para leer imágenes de la base datos
<?
$numero=$_REQUEST['n'];
$base="ejemplos";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
    $sacar = "SELECT * FROM ".$tabla." WHERE (num_ident=$numero)" ;
    $resultado = mysql_query($sacar,$conexion);
while ($registro = mysql_fetch_array($resultado)){
            $tipo_foto=$registro['formato'];
             header("Content-type: $tipo_foto");
             echo $registro['imagen'];
}
mysql_close();
?>
Ver imágenes guardadas

El problema de los PNG en IE

El JavaScript que asigna la transparencia a las imágenes en formato png las identifica buscando la coincidencia de los tres últimos caracteres del nombre de la imagen con la extensión png.

Cuando se trata de imágenes dinámicas el nombre de la imagen coinciden con el nombre de la llamada al script que se utiliza para su visualización. Por eso, para advertir a JavaScript de que se trata de una imagen png hemos incluido el condicional que puedes ver en el ejemplo. De esa forma, cuando se trata de una imagen en este formato incluimos en la petición una variable con el valor png de forma que pueda ser reconocida por pngfix.js y aplicada la transparencia requerida. Script para leer la base de datos
<html>
<head>
<!-- al margen te comentamos la razón por la que -->
<!-- se incluyen estas líneas en rojo -->
<!--[if IE ]>
<script type="text/javascript" src="pngfix.js"></script>
<![endif]-->
</head>
<body>
<?
$base="ejemplos";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
    $sacar = "SELECT * FROM ".$tabla;
    $resultado = mysql_query($sacar,$conexion);
while ($registro = mysql_fetch_array($resultado)){
  print "<center>Titulo de la imagen: ".$registro['nombre']."<br>";
/* la inclusión de este condicional obedece a los problemas que plantea
   la visualización de las transparencias
   de las imágenes png en Internet Explorer.
   Al margen justificamos las razones de su inclusión */
  if($registro['formato']=="image/png"){
  print "<img src='ver_foto.php?n=".$registro['num_ident']."&v=png'><br>";
  }else{
  print "<img src='ver_foto.php?n=".$registro['num_ident']."'><br>";
  }
  print "Tamaño de la imagen: ".$registro['tamano']." bytes
</center>"; } mysql_close(); ?> </body> </html>