<?php
/*!
@copyrights b23|prod:Tiana Bruno RAKOTOARIMANANA - 2004 (all rights reserved to author)
@author Tiana Bruno RAKOTOARIMANANANA
@date Sat Sep 18 15:41:32 CEST 2004 @612 /Internet Time/
@filename php_image.class.inc
*/
if(!isset($classeImage)) {
$classeImage = 1;
require_once("php_tbl.class.inc.php");
/*!
@class Image
@abstract Elle va definir une image dont l'affichage est gere par la libraire GD de PHP. Les deux constructeurs permettent deux types de creation de l'image: depuis un fichier (generalement temporaire) et depuis une chaine binaire (venant generalement d'une base SQL)
Prise en charge du format JPEG UNIQUEMENT | SQL | Les Images sont stockees dans la table Image de la base SQL sous forme binaire.
@discussion this could be ported to an other data format like mp3, avi, etc.
*/
define("MEMORY_LIMIT", @ini_get("memory_limit"));
if(!MEMORY_LIMIT) define("MEMORY_LIMIt", 20000000);
define ("JPEG_QUALITY", 100);
class Image {
var $img; // ressource image (GD2)
var $id; // dans la base SQL
var $file;
var $nom;
var $desc;
var $size; // en % format: $n OU en px: format:$nX."x".$nY
var $mime;
var $debug;
/** @constructor Image
@abstract constructeur libre
@param file file resource or null.
@param debug activate debug log
@param size preferred size
@discussion
*/
function Image($debug = false, $file = null, $size="100") {
$this->debug = $debug;
$this->file = $file;
$this->mime = null;
$this->size = $size;
if($this->debug) error_reporting(E_ALL);
else error_reporting(E_COMPILE_WARNING);
}
/* ----- partie privée ----- */
/** @param f resource fichier ou chemin String, si $this->file est accessible alors les donnes y seront lues
@return String|boolean donnes lues ou false */
function loadFile($f = null) {
trigger_error("Tentative d'ouverture du fichier $f ...", E_USER_NOTICE);
if(is_readable($f)) {
trigger_error("fichier lisible", E_USER_NOTICE);
$this->file = fopen($f, "rb");
if(!is_resource($this->file))
die("Lecture impossible!");
} else if (is_resource($f)){
$this->file = $f;
} else if (!is_resource($this->file))
return false;
$imagedata = '';
while(!feof($this->file)) {
trigger_error("[]",E_USER_NOTICE);;
$imagedata .= fgets($this->file, 4096);
}
fclose($this->file);
$this->file = null;
// image ressource
$this->loadBin($imagedata,$this->nom);
trigger_error("Fichier charg!", E_USER_NOTICE);
return $imagedata;
}
function loadBin (&$string,$nom="") {
// init nom
if($nom == "")
$this->setNom("Image".time('U'));
else
$this->setNom($nom);
// init img
$this->img = imagecreatefromstring($string);
if(!is_resource($this->img))
$this->erreurJpeg();
trigger_error("Donnes charges!", E_USER_NOTICE);;
return $this->img;
}
function erreurJpeg() {
// gestion d'erreur JPG: créer une image vide
$this->img = imagecreate(@$this->getWidth() + 64, @$this->getHeight() + 64); /* Création d'une image blanche */
$bgc = imagecolorallocate($this->img, 255, 255, 255);
$tc = imagecolorallocate($this->img, 0, 0, 0);
imagefilledrectangle($this->img, 0, 0, 150, 30, $bgc);
// Affichage d'un message d'erreur
imagestring($this->img, 5, -3+$this->getWidth()/2 , -3+$this->getHeight()/2, "N/A", $tc);
}
/** @param f chemin vers le fichier o sera crite l'image ou une chaine vide pour afficher sur l'output */
function paint($f = null) {
if(!is_resource($this->img)) {
trigger_error("Image::paint() hasn't found any image resource.", E_USER_WARNING);
return false;
}
if($f != null){
if(!is_resource($this->file = fopen($f, "wb")))
trigger_error("Image::paint($f) systme inaccessible!", E_USER_ERROR);
fclose($this->file);
if(!is_writable($f)) {
if(!chmod($f, 0777))
trigger_error("Image::paint($f) protection en criture dtecte!", E_USER_ERROR);
}
} else header("Content-type: ".$this->mime);
switch($this->mime) {
case "image/wbmp":
return imagewbmp($this->img, $f);
case "image/jpeg":
case "image/jpg":
return imagejpeg($this->img, $f, JPEG_QUALITY);
break;
case "image/gif":
return imagegif($this->img, $f);
break;
case "image/png":
return imagepng($this->img, $f);
break;
default:
die ("Pas de support $this->mime sur cette page.");
break;
}
}
function getSize($im, $pw = null, $ph = null) {
$w = $pw; $h = $ph;
if(isset($pw)) $w = $pw;
if(isset($ph)) $h = $ph;
if(!isset($w) || $w == 0) $w = imagesx($im)/imagesy($im) * $h;
if(!isset($h) || $h == 0) $h = imagesy($im)/imagesx($im) * $w;
if($w == 0 && $h == 0) { $w = imagesx($im); $h = imagesy($im); }
return array($w,$h);
}
/* ----- partie publique ----- */
function setFile(&$file) {
$this->file =& $file;
}
function setNom($nom) {
$this->nom = $nom;
}
function setId($id) {
$this->id = $id;
}
function setDesc($desc) {
$this->desc = $desc;
}
function setSize($size="100") { // pour le zoom $size=int() et en px size=string(int()."x".int())
$this->size = $size;
}
/** @return HTML format width and height options */
function strSize() { // retourne un array(sizex[%;px],sizey[%;px])
if(!strrpos($this->size,'x')) // zoom (%)
return array("nX" => $this->size."%","nY" => $this->size."%");
else { // redimensionner (resample)
$nX = substr($this->size,0,strrpos($this->size,'x'));
$nY = substr($this->size,strrpos($this->size,'x')+1,strlen($this->size));
return array("nX" => $nX,"nY" => $nY);
}
}
function getWidth() {
if(!is_resource($this->img)) {
trigger_error("Image::getWidth() image has no resource.zero returned", E_USER_WARNING);
return 0;
}
$s = $this->getSize($this->img);
return $s[0];
}
function getHeight() {
if(!is_resource($this->img)) {
trigger_error("Image::getHeight() image has no resource.", E_USER_WARNING);
return 0;
}
$s = $this->getSize($this->img);
return $s[1];
}
function resize() {
if(is_resource($this->img)) {
if(isset($this->size)) {
$src = $this->img;
$width = imagesX($this->img);
$height = imagesY($this->img);
$size = $this->strSize();
$new_height = $size["nY"];
$new_width = $size["nX"];
if(strrpos($new_width,'%')) {
$new_width = (int) ($width * (substr($size["nX"], 0, -1)/100));
$new_height = (int) ($height * ($new_width/$width));
} else { // resizing to match square area of $size["nX"];$size["nY"], Aspect ratio preserved
if($width > $new_width) {
$new_height = (int) ($height * ($new_width/$width));
}
if($new_height > $size["nY"]) {
$new_width = (int) ($new_width * ($size["nY"] / $new_height));
$new_height = $size["nY"];
}
if($width < $new_width) {
if($height > $new_height)
$new_width = (int) ($width * ($new_height/$height));
}
}
$dst = imagecreatetruecolor($new_width,$new_height);
imagecolortransparent($dst, imagecolortransparent($src));
imagecopyresampled($dst,$src,0,0,0,0,$new_width,$new_height,$width,$height);
$this->img = $dst;
$this->setSize($new_width."x".$new_height);
return true;
}
}
else trigger_error("Image::resize() image has no resource.", E_USER_WARNING);
}
function setMime($mime) {
$this->mime = $mime;
}
function getExtension() {
if(!isset($this->mime)) trigger_error("Image::getExtension() No mime type defined!", E_USER_NOTICE);
return substr(strstr($this->mime, '/'), 1);
}
// wrapper loadFile
function loadFromFile($name = null) {
return $this->loadFile($name);
}
// wrapper loadBin()
function loadFromBinary(&$string,$nom="image") {
$this->loadBin($string,$nom="image");
}
// wrapper erreurJpeg
function loadError() { $this->setMime("image/jpeg"); $this->erreurJpeg(); }
/** @param mode 0 means GD resource to image tag,
1 is standard output print,
2 uses file resource to bring image tag
3 zend_log image tag
@param link add a file link to image (needs write permissions)
@return boolean true or false*/
function afficher($mode=0, $link = null) { /*--- status:OK!!*/
if($mode==1){
// conversion de la sortie pour les images
mb_http_output("pass");
/* enclenchement de la bufferisation de sortie --output buffering--, fonction callback qui appelle la fonction de conversion avant l'envoi de la sortie au navigateur. Les entetes http ne sont pas affectés, ils sont envoyés à leur apppel.*/
ob_start("mb_output_handler");
if(isset($this->file)) {
if(!isset($this->img))
$this->loadFile();
}
$this->resize();
ob_clean();
if(!$this->paint()) {
trigger_error("Image::afficher($mode) Erreur lors de l'affichage de l'image!", E_USER_WARNING);
return false;
}
ob_end_flush();
return true;
} else if($mode == 2) {
if(isset($this->file)) {
if(is_resource($this->file)) {
$this->loadFile();
}
else {
trigger_error("Image::afficher($mode) file has not found any resource.", E_USER_NOTICE);
return false;
}
} else {
trigger_error("Image::afficher($mode) no file set has been set.", E_USER_NOTICE);
return false;
}
} else if($mode == 3) {
// logo zend
$link = "zend_logo.png";
$this->img = zend_logo_guid();
$this->mime = "image/png";
}
if(is_null($link)) {
trigger_error("Image::afficher($mode) param link has to be set.", E_USER_ERROR);
return false;
}
if(!$this->paint($link)) return false;
echo HTML_image($link,array("javascript" => array('onClick' => "window.open('".$link."','b23::Open Window ^','width=this.width*4, height=this.height*4, status=no, directories=no, toolbar=no, location=no, menubar=no,scrollbars=no, resizable=yes'")));
return true;
}
/** @param mode 0 returns an table tag; 1 prints it to standard HTML output */
function afficherCadre ($mode=0, $desc=TRUE) {
$tbl = new Tableau (2,1, str_replace(" ", "_", $this->nom."(".$this->mime.")"));
$tbl->setOptionsArray(array("class" => "image"));
$tbl->setContenu_Cellule(0,0, "<center>".$this->afficher(0, $this->nom.".".$this->getExtension())."<center>");
if($desc)
$tbl->setContenu_Cellule(1,0, $this->nom." : ".$this->desc);
else
$tbl->setContenu_Cellule(1,0, "<center>".$this->nom."</center>");
if($mode == 0)
return $tbl->fin(1); // HTML
if($mode == 1)
$tbl->fin(); // to stdout
return true;
}
/* PRINCIPALES ---- fonctions vers/depuis la base SQL */
// wrappers
function ToSQL ($sql) {$this->saveToSQL($sql);}
function FromSQL($sql,$id) { $this->loadFromSQL($sql,$id); }
/** writes to SQL the picture content loaded
@return int id for fetching it */
function saveToSQL ($sql) {
if($this->img != null) {
trigger_error("tentative d'ouverture du fichier temporaire..", E_USER_NOTICE);
$f = tempnam("", "b23IOSQL_buffer");
$this->paint($f);
if(!$sql->query("INSERT INTO image (nom, image, description,mime) VALUES (\"".addslashes($this->nom)."\", \"\", \"".addslashes($this->desc)."\",\"".$this->mime."\")")) die("L'image n'a pas correctement ete stockee sur la base SQL: ".mysql_error());
// init id
$this->setId(mysql_insert_id($sql->connexion));
$imagedata = file_get_contents($f);
if(!$imagedata)
die("Pas de donnes temporaires trouves!\n");
// insertion du contenu de l'image
trigger_error("Tentative de stockage sur la BD...", E_USER_NOTICE);
//if(!$sql->query("UPDATE image SET image=LOAD_FILE('$this->file') WHERE id=$this->id")) die("L'image n'a pas correctement ete stockee sur la base SQL: ".mysql_error());
if(!$sql->query("UPDATE image SET image=\"".addslashes($imagedata)."\" WHERE id=$this->id")) die("L'image n'a pas correctement ete stockee sur la base SQL: ".mysql_error());
// retourner l'id de l'image ainsi stockée pour ne pas perdre sa trace
unlink($f);
trigger_error("OK! id: $this->id", E_USER_NOTICE);
return $this->id;
} else die ("image.class: ToSQL: Pas d'image charge!!!");
}
/** reads from SQL the picture previously stored
@return true if succeeded or false and loads N/A error */
function loadFromSQL ($sql, $id) {
$image = $sql->query("SELECT * FROM image WHERE id = '$id'");
if($img = $sql->LigneSuivante_Array($image)) {
$nom = stripslashes($img['nom']);
$this->desc = stripslashes($img['description']);
$this->setId($id);
$this->loadBin(stripslashes($img['image']), $nom);
$this->mime = stripslashes($img["mime"]);
return true;
} else { // il n'y a pas d'image correspondant a id dans la table
$this->loadError();
return false;
}
}
function DeleteSQL ($sql, $id) {
if($sql->query("DELETE FROM image WHERE id = $id"))
return TRUE;
else return FALSE;
}
}
}
?>