Publicidad:
La Coctelera

Sergio.Iglesias - Diseño y desarrollo web

recursos sobre diseño web con estándares, programación web, usabilidad, accesibilidad...

26 Octubre 2006

Guardar una imagen y su miniatura a un campo Blob de mysql

¿Qué necesitamos?

Para crear la miniatura necesitamos la Librería Gráfica GD, en este script estamos usando la versión 2.0.28 de esta librería.

Si no la tenemos activada solo tenemos que modificar el archivo php.ini que se encuentra en C:\Windows (puede variar según tu versión de Windows), y agregar la línea extension=php_gd2.dll en la sección "Dynamic Extensions". El archivo php_gd2.dll debe estar en la carpeta "extensions" dentro del directorio donde instalaste el php, por ejemplo "C:\php\extensions". Si no tienes el archivo php_gd2.dll, te lo puedes descargar aquí.

Desarrollo del Script

El formulario de upload y el script php está en una sola página, la nombré como blob.php, empezemos entonces:

php:
<?php
 
 // Verificamos que el formulario no ha sido enviado aun
 $postback = (isset($_POST["enviar"])) ? true : false;
 if($postback){
 
   // Nivel de errores
   error_reporting(E_ALL);
   // Constantes
   # Altura de el thumbnail en píxeles
   define("ALTURA", 100);
   # Nombre del archivo temporal del thumbnail
 
   define("NAMETHUMB", "/tmp/thumbtemp"); //Esto en servidores Linux, en Windows podría ser:
 // define("NAMETHUMB", "c:/windows/temp/thumbtemp"); y te olvidas de los problemas de permisos
   # Servidor de base de datos
 
   define("DBHOST", "localhost");
   # nombre de la base de datos
   define("DBNAME", "test");
   # Usuario de base de datos
   define("DBUSER", "root");
   # Password de base de datos
 
   define("DBPASSWORD", "");
   // Mime types permitidos
   $mimetypes = array("image/jpeg", "image/pjpeg", "image/gif", "image/png");
   // Variables de la foto
 
   $name = $_FILES["foto"]["name"];
   $type = $_FILES["foto"]["type"];
   $tmp_name = $_FILES["foto"]["tmp_name"];
   $size = $_FILES["foto"]["size"];
   // Verificamos si el archivo es una imagen válida
 
   if(!in_array($type, $mimetypes))
     die("El archivo que subiste no es una imagen válida");
   // Creando el thumbnail
   switch($type) {
 
     case $mimetypes[0]:
     case $mimetypes[1]:
       $img = imagecreatefromjpeg($tmp_name);
       break;
     case $mimetypes[2]:
       $img = imagecreatefromgif($tmp_name);
       break;
     case $mimetypes[3]:
       $img = imagecreatefrompng($tmp_name);
       break;
   }
 
   $datos = getimagesize($tmp_name);
   $ratio = ($datos[1]/ALTURA);
   $ancho = round($datos[0]/$ratio);
   $thumb = imagecreatetruecolor($ancho, ALTURA);
   imagecopyresized($thumb, $img, 0, 0, 0, 0, $ancho, ALTURA, $datos[0], $datos[1]);
   switch($type) {
 
     case $mimetypes[0]:
     case $mimetypes[1]:
       imagejpeg($thumb, NAMETHUMB);
 	  break;
     case $mimetypes[2]:
       imagegif($thumb, NAMETHUMB);
       break;
     case $mimetypes[3]:
       imagepng($thumb, NAMETHUMB);
       break;
   }
 
   // Extrae los contenidos de las fotos
   # contenido de la foto original
   $fp = fopen($tmp_name, "rb");
   $tfoto = fread($fp, filesize($tmp_name));
   $tfoto = addslashes($tfoto);
   fclose($fp);
   # contenido del thumbnail
 
   $fp = fopen(NAMETHUMB, "rb");
   $tthumb = fread($fp, filesize(NAMETHUMB));
   $tthumb = addslashes($tthumb);
   fclose($fp);
   // Borra archivos temporales si es que existen
 
   @unlink($tmp_name);
   @unlink(NAMETHUMB);
   // Guardamos todo en la base de datos
   #nombre de la foto
   $nombre = $_POST["nombre"];
   $link = mysql_connect(DBHOST, DBUSER, DBPASSWORD) or die(mysql_error($link));;
   mysql_select_db(DBNAME, $link) or die(mysql_error($link));
   $sql = "INSERT INTO tabla(nombre, foto, thumb, mime)
     VALUES
     ('$nombre', '$tfoto', '$tthumb', '$type')";
   mysql_query($sql, $link) or die(mysql_error($link));
   echo "Fotos guardadas";
   exit();
 
 }
 ?>
html:
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 
 <title>Imagen a Blob</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 
 <body>
 <form name="frmimage" id="frmimage" method="post"
 	enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF'];?>">
 
 	Nombre: <input type="text" id="nombre" name="nombre" /><br />
 	Imagen: <input type="file" id="foto" name="foto" /><br />
 
 	<input type="submit" name="enviar" id="enviar" value="Guardar" />
 </form>
 </body>
 </html>
 
  

Las primeras líneas controlan que el formulario aun no se ha enviado, despues definimos constantes para guardar los archivos en nuestra base de datos, solo las cambiamos según nos convenga.

Despues verificamos si el archivo que subimos es una imagen para esto verificamos su tipo MIME. Los tipos que se permiten en este script son "image/jpeg" , "image/gif" e "image/png". Caso contrario recibiremos el mensaje "El archivo que subimos no es una imagen válida".

Según el tipo MIME de la imagen, crearemos la miniatura con las funciones imagecreatefromjpeg(), imagecreatefromgif() o imagecreatefrompng().

La función imagecopyresized() crea la miniatura de la imagen, aunque también podemos utilizar imagecopyresampled().

Y aquí el script que utilizé para la tabla:

sql:
CREATE TABLE `tabla` (
   `idfoto` int(3) NOT NULL AUTO_INCREMENT,
   `nombre` varchar(255) NOT NULL DEFAULT '',
   `foto` blob NOT NULL,
   `thumb` blob NOT NULL,
   `mime` varchar(40) NOT NULL DEFAULT '',
   PRIMARY KEY  (`idfoto`)
 
 ) ;

Ustedes ya le agregan los campos que necesiten.

Actualización

Dado que el soporte GIF fue retirado por completo de la biblioteca GD en la versión 1.6, la función imagegif no se encuentra disponible si está usando tal versión de la biblioteca GD. Se espera que el soporte para esta característica regrese en una versión posterior al relanzamiento del soporte GIF en la biblioteca GD a mediados de 2004. Para más información, consulte el sitio web del Proyecto GD.

Para que nuestro script funcione corréctamente la carpeta que lo contiene debe tener permisos de escritura, la mayoría de hostings que ofrecen PHP tienen los archivos bajo la carpeta public_html, no se sugiere correr este script bajo la carpeta raiz, ya que si damos permisos de escritura a public_html otros usuarios pueden acceder y modificar nuestros archivos. La sugerencia es correr el script bajo una carpeta cualquiera diferente de la raiz, por ejemplo /thumbs/blob.php, asi no tendremos problemas de seguridad.

Actualización 2

Agregué al script en el arreglo de mimes el tipo "image/pjpeg" para que no haya problemas al subirlo, también a sugerencia de mi master Alex cambié la ruta de la NAMETHUMB, para que se guarde en la carpeta temporal del SO en el que se ejecuta. Si es windows entonces c:\Windows\Temp\ y si es linux /tmp/, etc.

Enlaces

Autor

Braulio Andrés Soncco Pimentel

Programador - Diseñador

braulio at buayacorp.com

servido por Sergio 5 comentarios compártelo

5 comentarios · Escribe aquí tu comentario

alicia

alicia dijo

hola probe el programa pero me da errores en windows por q dice que el permiso es denagado soy nueva en usar php, no me guarda la miniatura solo la imagen grande y tira advertencias fopen(), fread, fsize como le hago ayuuuuuuuudaaaaaaaa

7 Mayo 2008 | 01:31 AM

Sergio

Sergio dijo

Mira todo el tema de permisos. Es el fallo más habitual en estos casos.

7 Mayo 2008 | 09:13 AM

Juan Francisco

Juan Francisco dijo

Hola, necesito ayuda, pues me salen estos errores y son como con los permisos,

Warning: fopen(c:/windows/temp/thumbtemp) [function.fopen]: failed to open stream: Permission denied in c:\wamp\www\prueba_imagen\index.php on line 68

Warning: fread(): supplied argument is not a valid stream resource in c:\wamp\www\prueba_imagen\index.php on line 71

Warning: fclose(): supplied argument is not a valid stream resource in c:\wamp\www\prueba_imagen\index.php on line 73
Fotos guardadas

16 Junio 2008 | 04:31 AM

viviana

viviana dijo

necesito saber como guardar una imagen en una base de datso realozada en sql para luego utilizar en la programacion de c#

7 Agosto 2008 | 06:12 PM

gabo peña

gabo peña dijo

hola, tengo un problema, ya eh manejado este tipos de archivos, osea fotos y todo jala muy bien.
solo que al momento de querer ver los archivos si se pueden ver y todo bien, pero me hace un temporal en el ftp y se van haciendo muchos, cada ves que entras a ver todas las fotos, y no se eliminan, las tengo que eliminar manualmente dentro del ftp. hay algun programa para que las elimine????

gracias si me pueden responder lo agradesere mucho

5 Diciembre 2008 | 12:36 AM

Escribe tu comentario


Sobre mí

Avatar de Sergio

Sergio.Iglesias - Diseño y desarrollo web

Fuentesaúco, España
ver perfil »
contacto »
Mi nombre es Sergio Iglesias. Trabajo como diseñador y desarrollador web.

Fotos

Sergio Iglesias todavía no ha subido ninguna foto.

¡Anímale a hacerlo!

Buscar

suscríbete

Selecciona el agregador que utilices para suscribirte a este blog (también puedes obtener la URL de los feeds):

¿Qué es esto?

Crea tu blog gratis en La Coctelera