kurtkuzu
10-11-2007, 23:22 PM
Pixmap kullanımı ile ilgili makalenin birinci bölümünde PHP-Gtk içerisinde resim kullanabilmenin tek yolunun XPM kullanmak olduğunu ve jpg,png vb diğer resim formatlarını kullanabilmek için 3.parti uygulamalar kullanarak veya PHP nin GD kütüphanesini kullanarak önce bu resimleri XPM formatına çevirip daha sonrada bunları kullanabileceğimizi belirtmiştik. Şimdi Jonathan Gotti tarafından yazılmış, PHP nin GD kütüphanesini kullanarak değişik resim formatlarından XPM verileri hazırlamayı olanaklı kılan kütüphanenin kullanımına ilişkin açıklamalar bulacaksınız bu yazıda. Yazının sonunda kodları bulunan kütüphane, bir uygulamanın parçası olduğu için, kullanacağımız fonksyionlardaki bazı parametreleri hiçbirzaman kullanmayacağız.ve bu kütüphanedeki 3 fonksiyon hakkında açıklamalar bulacaksınız.
1-image2xpm_d fonksiyonu
Kullaanım şekli:
image2xpm_d(resource resim,[boolean trans=true,[object progress=null]]);
biçiminde kullanılan bu fonksiyon XPM haricindeki bir resim formatını XPM e çevirmek için kullanacağımız fonksiyondur. Bu fonksiyon XPM verilerini içeren bir array döndürür.
Birinci parametre PHP nin GD kütüphanesindeki fonksiyonlar aracılığı ile oluşturacağımız bir resim handler i olacaktır.
İkinci ve üçüncü parametreyi kullanmayacağız.
Örneğin Jpg formatındaki bir resimi XPM e çevirmek içinCode:
<?php
// resim handlerini oluşturuyoruz
$resim=imagecreatefromjpg("resim.jpg");
// elde edilen resource tipindeki veriyi
// XPM verisi elde edecek fonksiyona veriyoruz
$xpmdata=image2xpm_d($resim);
// işimiz bitincede resimin hafızadan silinmesini sağlıyoruz
imagedestroy($resim);
Diğer formatlardaki resimleride bu yolu izleyerek XPM verilerine dönüştürebilirsiniz. Dikkat etmeniz gereken husus hangi resim formatını kullanacaksanız GD fonksiyonlarındaki ilgili fonksiyonu kullanarak bir resim handleri oluşturmanız gerektiğidir. Aşağıda GD kütüphanesinin bu fonksiyonları verilmiştir
imagecreatefromjpeg
imagecreatefromgif
imagecreatefrompng
imagecreatefrombmp
imagecreatefromwbmp
imagecreatefromxbm
2-xpm_resize fonksiyonu
Kullanım şekli:
xpm_resize(mixed XPMverisi,int ciktiGenisligi,int ciktiYuksekligi,[object progress=null]);
Birinci parametre boyutlandırılması istenilen XPM verisidir.
İkinci parametre XPM çıktısının istenen genişliği
Üçüncü parametre XPM çıktısının istenen yükeskliği ni belirtir.
Bu fonksiyon ile XPM resimlerini yeniden boyutlandırabilirsiniz.Boyutlandırmayı en yakın komşusuna göre yapar.
Code:
<?php
// 640x480 boyutunda bir resmimiz olduğunu varsayalım
// ve bize 200x150 boyutunda resim gerekiyor olsun
// önce yukarıda yaptığımız işlemleri gerçekleştiriyoruz
$resim=imagecreatefromjpg("resim.jpg");
// elde edilen resource tipindeki veriyi
// XPM verisi elde edecek fonksiyona veriyoruz
$xpmdata=image2xpm_d($resim);
// işimiz bitincede resimin hafızadan silinmesini sağlıyoruz
imagedestroy($resim);
//sonrada XPM verisini yeniden boyutlandırma işlemine tabi tutuyoruz
$yeniXPM=xpm_resize($xpmData,200,150);
// böylece 200x150 boyutunda bir XPM verisi elde ederiz
Bu işlemi sadece XPM formatındaki bir resimede uygulayabiliriz.
3-xpmd_2file fonksiyonu
Bu fonksiyon XPM verilerini .xpm uzantılı bir dosyaya yazar.
Bu fonksiyon XPM haricindeki resimleri her seferinde XPM e çevirmek yerine, çevrilmiş olan XPM resmini bir .xpm dosyasına yazarak, XPM resmine bu dosya aracılığı ile erişmek amacıyla kullanılabilir. Bu bize hız ve zaman kazandırır. Tabi eğer XPM formatında olmayan resimi bir defaya mahsus kullanacaksanız veya kullanım oranı az olacaksa bu fonksiyonu kullanmamanızı öneririm.
Kullanım şekli:
xpmd_2file(array xpmVerisi,string dosyaIsmi);
Birinci parametre saklanacak olan XPM verisidir.
İkinci parametre XPM verisinin kaydedileceği dosya ismidir.
Örnek: Code:
<?php
// resim handlerini oluşturuyoruz
$resim=imagecreatefromjpg("resim.jpg");
// elde edilen resource tipindeki veriyi
// XPM verisi elde edecek fonksiyona veriyoruz
$xpmdata=image2xpm_d($resim);
// işimiz bitincede resimin hafızadan silinmesini sağlıyoruz
imagedestroy($resim);
// XPM verisini dosyaya yazıyoruz
xpmd_2file($xpmdata,"resim");
// böylece resim.jpg yeniden çevirme işlemine tabi tutmadan
// kullanma imkanına kavuşmuş oluyoruz.
list($pixmap,$mask)=gdk::pixmap_create_from_xpm("resim.xpm");
XPM harici resim formatlarının PHP-Gtk ile kullanımını anlatmaya çalıştığım bu yazının sonunda, PHP-Gtk 2 içerisinde bukadar karmaşaya gerek kalmadan direkt olarak farklı resim resim formatlarını hatta animasyon kullanabileceğimizi müjdeleyerek bitirmek istiyorum. PHP-Gtk 2 ye ilişkin dökümantasyon (henüz) olmadığı için bu konuyla ilgili ayrıntılı bilgiyi şimdilik veremiyorum.
fix-img kütüphane kodları:
Code:
<?php
<?php
/**
* @author Jonathan Gotti <nathan at the-ring dot homelinux dot net>
* @copyleft (l) 2003-2004 Jonathan Gotti
* @package processing
* @subpackage FX-img
* @license http://opensource.org/licenses/gpl-license.php GNU Public
* License
*/
/**
* xpm resizing (nearest neighbour method)
* @param mixed $xpmsource string path to xpm file or array xpm data
* @param int $w_out the width output
* @param int $h_out the height output
* @return xpmdatas
*/
function xpm_resize($xpmsource,$w_out,$h_out,$progress=null ){
# check correct size input
settype($w_out,'int'); settype($h_out,'int');
if( $w_out<=0 || $h_out<=0) return FALSE;
# Check input type
if(!is_array($xpmsource)){
if(! $xpmsource = xpm2xpm_d($xpmsource))
return FALSE;
}
# get xpmdatas infos
if(! preg_match("!(\d+)\s+(\d+)\s+(\d+)\s+(\d+)!",$xpmsource[0],$m))
return FALSE;
$w_in = $m[1];
$h_in = $m[2];
$col_nb = $m[3];
$col_chr= $m[4];
#copy data headers
$out[0] = "$w_out\t$h_out\t$col_nb\t$col_chr";
# retrieve indexed palette
if($progress){
$progress->set_format_string('read palette');
gtkgui_refresh();
}
for($i=1;$i<=$col_nb;$i++){
if(preg_match("!(.{".$col_chr."})\s+c\s+#([0-9a-f]{6}|none)!i",
$xpmsource[$i],$mcol))
$palette[$mcol[1]]=$mcol[2];
else
$palette[str_repeat('~',$col_chr)]='None';
# if we can't retrieve the color value we forced it to none
#copy palette to new datas
$out[$i] = $xpmsource[$i];
if($progress){
$progress->set_percentage(($i)/$col_nb);
gtkgui_refresh();
}
}
$colorids = array_flip($palette);
#Now resizing
$w_ratio = $w_in/$w_out;
$h_ratio = $h_in/$h_out;
if($progress){
$progress->set_format_string('resizing');
gtkgui_refresh();
}
for($i=0;$i<$w_out;$i++){ # for each output row
$x_src = intval($i*$w_ratio);
for($y=0;$y<=$h_out;$y++){ # for each output column
$y_src = intval($y*$h_ratio);
$out[$y+($col_nb+1)] .= substr($xpmsource[$y_src+($col_nb+1)],
$col_chr*$x_src,$col_chr);
}
if($progress){
$progress->set_percentage($i/$w_out);
gtkgui_refresh();
}
}
return $out;
}
/*
* return an xpm data array from a xpm file
* @param string $file path to the xpm file
* @return array() xpm datas (FALSE on error)
*/
function xpm2xpm_d($file){
if(! $array = file($file))
return FALSE;
# reading and formating xpmdata
foreach($array as $lineid=>$line){
if(! $started){
if(! preg_match("!\"\d+\s+\d+\s+\d+\s+\d+\",!",$line) )
#detect the first interesting line
continue;
$array[$lineid] = preg_replace("![\",\n]!","",$line);
$started = TRUE;
# bool value to know if we've start or not to format xpmdata
$startline = $lineid;
}else{ # format xpm datas
$array[$lineid] = preg_replace("!^\s*\"([^\"]+)\"\s*,\s*$!","\\1",$line);
if(preg_match("!(\"([^\"]+)\")?\s*}\s*;!",$line,$m)){ # is this the end
if(!$m[2]){
$endline = $lineid-1;
}else{
$array[$lineid] = $m[2];
$endline = $lineid;
}
}
}
}
# clean array
while(count($array)>$endline+1)array_pop($array);
# delete eventually un-needed end
for($i=0;$i<$startline;$i++)array_shift($array);
# delete xpm headers
return $array;
}
/**
* return the size of a xpm file or data
* @param mixed $xpm (string filename or xpmdata array)
* @return array(width,height)
*/
function xpm_getsize($xpm){
if(is_file($xpm)){
if(! ($xpm = fopen($xpm,'r')) )
return FALSE;
while($line = fread($xpm,4096)){
if(preg_match("!(\d+)\s+(\d+)\s+\d+\s+\d+!",$line,$m))
break;
}
}elseif(is_array($xpm)){
if(! preg_match("!(\d+)\s+(\d+)\s+\d+\s+\d+!",$xpm[0],$m))
return FALSE;
}
if(! count($m)==3)
return FALSE;
array_shift($m);
return $m;
}
/**
* get the image palette
* @author
jonathan.gotti@free.fr
* @date 2003-12-20
* @param ressource image $img
* @return array
*/
function imagegetpalette($img){
# echo imagecolorstotal($img)."colors found\n";
$width = imagesx($img);
$height= imagesy($img);
//try an alternate method since the image is a paletted image
//better 5 or 6 seconds on a 1280x1024 png 256clrs
for($i=0;$i<imagecolorstotal($img);$i++){
$colors[$i]=imagecolorsforindex($img,$i);
}
return $colors;
}
/**
* get a xpm style palette from a gd one
* @author
jonathan.gotti@free.fr
* @date 2003-12-20
* @param array $gdpalette
* @param string $indexed_type 'gd' keep the gd_index,'xpm' indexed
* by xpm char code
* @param string $value_type 'char_code' the xpm char code index,
* 'color' the xpm color value,'both' associated value is are array containing
* xpm char code and xpm color value
* @param array $trans array of transparent color values
* @return array
*/
function gd2xpmpalette($gdpalette,$indexed_type='xpm',
$value_type='color',$trans=null){
if($GLOBALS['VERBOSE'])
echo "transform to xpm palette \n";
$nb_colors = count($gdpalette);
if($indexed_type=='xpm' || $value_type!='color'){
//initialize char array if needed
$first_char = 48;//lowest used ASCII char code
$last_char = 126;//highest used ASCII char code
$nb_char = intval(log($nb_colors)/log($last_char-$first_char))+1;
//Thanks to my friend RHONONO for this one
for($i=0;$i<=$nb_char;$i++){//initialize array of char
$chars[$i]=$first_char;
}
}
foreach($gdpalette as $gdindex => $gdcolor){
if($indexed_type=='xpm' || $value_type!='color'){
//recompose xpm character coding only if needed
$char_code = null;//initialise char_code
for($i=0;$i<$nb_char;$i++){//increment other chars
$chars[0]++;//increment chars
if($chars[$i]>$last_char){//check chars are in the good range
$chars[$i]=$first_char;
$chars[$i+1]++;
}
$char_code = chr(($chars[$i]==92?47:$chars[$i])) . $char_code ;
}
}
if($indexed_type == 'xpm')//choose indexed type
$outindex = $char_code;
else//assume gd indexed wanted
$outindex = $gdindex;
//the val acoording to it
switch($value_type){
case 'color':
if($gdcolor['alpha']>=127)
$out[$outindex] = 'None';
else
$out[$outindex] = strtoupper('#'.str_pad(dechex($gdcolor['red']),2,
'0',STR_PAD_LEFT).str_pad(dechex($gdcolor['green'])
,2,'0',STR_PAD_LEFT).str_pad(dechex($gdcolor['blue']),2,'0',STR_PAD_LEFT));
break;
case 'char_code':
$out[$outindex] = $char_code;
break;
case 'both':
if($gdcolor['alpha']>=127)
$out[$outindex] = array(0=>$char_code,1=>'None');
else
$out[$outindex] = array( 0=>$char_code,1=>strtoupper(
'#'.str_pad(dechex($gdcolor['red']),2,'0',STR_PAD_LEFT)
.str_pad(dechex($gdcolor['green']),2,'0',STR_PAD_LEFT).str_pad(
dechex($gdcolor['blue']),2,'0'
,STR_PAD_LEFT)));
break;
}
}
return $out;
}
/**
* get xpm_data from gd image resource
* @date 2003-12-20
* @param resource gd image $img
* @return xpm data
* @param gtkprogress &$progress is an optional progressbar to trace
* activity (will received a value between 0 to 100)
* @uses gtkgui_refresh, imagegetpalette, gd2xpmpalette,
*/
function image2xpm_d($img,$trans=TRUE,$progress=null){
# print_r($progress->adj);
$exectime_start=get_microtime();
if($GLOBALS['VERBOSE'])
echo "recomposing xpm data \n";
$w = imagesx($img);
$h = imagesy($img);
if(imageistruecolor($img) && $trans){
if($progress){
$progress->set_format_string('keep transparency');
gtkgui_refresh();
}
$imgtmp = imagecreatetruecolor($w,$h);
//creation d'une copie de l'image en mode palette
imagealphablending($imgtmp,FALSE);
# imagecopymerge($imgtmp,$img,0,0,0,0,$w,$h,100);
//pour en recuperer la palette
imagecopymerge($imgtmp,$img,0,0,0,0,$w,$h,100);
//pour en recuperer la palette
imagetruecolortopalette($imgtmp,TRUE,255);
$transindex = imagecolorallocate($imgtmp,1,1,1);
//set the trans color to a known one
$transindex = imagecolortransparent($imgtmp,$transindex);
if($progress){
$progress->set_format_string('read palette');
gtkgui_refresh();
}
$gdpalette = imagegetpalette($imgtmp);
if($progress){
$progress->set_format_string('XPMize palette');
gtkgui_refresh();
}
$palette = gd2xpmpalette($gdpalette,'gd','both');
list($color0k,$color0v )= each($palette);
$xpm_d[0]= "$w $h ".count($palette)." ".strlen($color0v[0]);//image definition
if($progress){
$progress->set_format_string('format palette');
gtkgui_refresh();
}
foreach($palette as $color){ //recompose palette_data
$xpm_d[]=$color[0]." c ".$color[1];
}
if($progress){
$progress->set_format_string('recomposing image');
gtkgui_refresh();
}
for($y=0;$y<$h;$y++){//recompose image
$row = null;
for($x=0;$x<$w;$x++){
$color = imagecolorsforindex($img,imagecolorat($img,$x,$y)) ;
//verifie la transparence sur l'image d'origine
$index = imagecolorat($imgtmp,$x,$y);
//recupere l'index de la couleur ds la copie qui
//nous a donné la palette
if($color['alpha']>126)
$row .= $palette[$transindex][0];
else
$row .= $palette[$index][0];
}
if($progress){
$progress->set_percentage(($y+1)/$h);
gtkgui_refresh();
}
$xpm_d[]=$row;
}
}else{
if(imageistruecolor($img))
imagetruecolortopalette($img,TRUE,255);
if($progress){
$progress->set_format_string('read palette');
gtkgui_refresh();
}
$gdpalette = imagegetpalette($img);
if($progress){
$progress->set_format_string('XPMize palette');
gtkgui_refresh();
}
$palette = gd2xpmpalette($gdpalette,'gd','both');
list($color0k,$color0v )= each($palette);
$xpm_d[0]= "$w $h ".count($palette)." ".strlen($color0v[0]);//image definition
if($progress){
$progress->set_format_string('format palette');
gtkgui_refresh();
}
$palette_num = count($palette);
foreach($palette as $color){//recompose palette_data
$xpm_d[]=$color[0]." c ".$color[1];
if($progress){
$progress->set_percentage(++$i/$palette_num);
gtkgui_refresh();
}
}
if($progress){
$progress->set_format_string('recomposing image');
gtkgui_refresh();
}
for($y=0;$y<$h;$y++){//recompose image
$row = null;
for($x=0;$x<$w;$x++){
$row .= $palette[imagecolorat($img,$x,$y)][0];
}
$xpm_d[]=$row;
if($progress){
$progress->set_percentage(($y+1)/$h);
gtkgui_refresh();
}
}
}
if(isset($imgtmp))
imagedestroy($imgtmp);
return $xpm_d;
}
/**
* write an xpm file from xpm data
* @author
jonathan.gotti@free.fr
* @date 2003-12-20
* @param array $xpm_d
* @param string $file
* @return bool
*/
function xpm_d2file($xpm_d,$file){
if($GLOBALS['VERBOSE'])
echo "write $file\n";
if(! $f = @fopen($file,'w'))
return FALSE;
fputs($f,"/* XPM */\nstatic char * ".basename($file)."[] = {\n");
foreach($xpm_d as $k => $row){
foreach ($row as $dt=>$nrow){
fputs($f,"\"$nrow\",");
fputs($f,"\n"); }
}
$pos = ftell($f);
fputs($f,"};");
fclose($f);
return TRUE;
}
function get_microtime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
?>
1-image2xpm_d fonksiyonu
Kullaanım şekli:
image2xpm_d(resource resim,[boolean trans=true,[object progress=null]]);
biçiminde kullanılan bu fonksiyon XPM haricindeki bir resim formatını XPM e çevirmek için kullanacağımız fonksiyondur. Bu fonksiyon XPM verilerini içeren bir array döndürür.
Birinci parametre PHP nin GD kütüphanesindeki fonksiyonlar aracılığı ile oluşturacağımız bir resim handler i olacaktır.
İkinci ve üçüncü parametreyi kullanmayacağız.
Örneğin Jpg formatındaki bir resimi XPM e çevirmek içinCode:
<?php
// resim handlerini oluşturuyoruz
$resim=imagecreatefromjpg("resim.jpg");
// elde edilen resource tipindeki veriyi
// XPM verisi elde edecek fonksiyona veriyoruz
$xpmdata=image2xpm_d($resim);
// işimiz bitincede resimin hafızadan silinmesini sağlıyoruz
imagedestroy($resim);
Diğer formatlardaki resimleride bu yolu izleyerek XPM verilerine dönüştürebilirsiniz. Dikkat etmeniz gereken husus hangi resim formatını kullanacaksanız GD fonksiyonlarındaki ilgili fonksiyonu kullanarak bir resim handleri oluşturmanız gerektiğidir. Aşağıda GD kütüphanesinin bu fonksiyonları verilmiştir
imagecreatefromjpeg
imagecreatefromgif
imagecreatefrompng
imagecreatefrombmp
imagecreatefromwbmp
imagecreatefromxbm
2-xpm_resize fonksiyonu
Kullanım şekli:
xpm_resize(mixed XPMverisi,int ciktiGenisligi,int ciktiYuksekligi,[object progress=null]);
Birinci parametre boyutlandırılması istenilen XPM verisidir.
İkinci parametre XPM çıktısının istenen genişliği
Üçüncü parametre XPM çıktısının istenen yükeskliği ni belirtir.
Bu fonksiyon ile XPM resimlerini yeniden boyutlandırabilirsiniz.Boyutlandırmayı en yakın komşusuna göre yapar.
Code:
<?php
// 640x480 boyutunda bir resmimiz olduğunu varsayalım
// ve bize 200x150 boyutunda resim gerekiyor olsun
// önce yukarıda yaptığımız işlemleri gerçekleştiriyoruz
$resim=imagecreatefromjpg("resim.jpg");
// elde edilen resource tipindeki veriyi
// XPM verisi elde edecek fonksiyona veriyoruz
$xpmdata=image2xpm_d($resim);
// işimiz bitincede resimin hafızadan silinmesini sağlıyoruz
imagedestroy($resim);
//sonrada XPM verisini yeniden boyutlandırma işlemine tabi tutuyoruz
$yeniXPM=xpm_resize($xpmData,200,150);
// böylece 200x150 boyutunda bir XPM verisi elde ederiz
Bu işlemi sadece XPM formatındaki bir resimede uygulayabiliriz.
3-xpmd_2file fonksiyonu
Bu fonksiyon XPM verilerini .xpm uzantılı bir dosyaya yazar.
Bu fonksiyon XPM haricindeki resimleri her seferinde XPM e çevirmek yerine, çevrilmiş olan XPM resmini bir .xpm dosyasına yazarak, XPM resmine bu dosya aracılığı ile erişmek amacıyla kullanılabilir. Bu bize hız ve zaman kazandırır. Tabi eğer XPM formatında olmayan resimi bir defaya mahsus kullanacaksanız veya kullanım oranı az olacaksa bu fonksiyonu kullanmamanızı öneririm.
Kullanım şekli:
xpmd_2file(array xpmVerisi,string dosyaIsmi);
Birinci parametre saklanacak olan XPM verisidir.
İkinci parametre XPM verisinin kaydedileceği dosya ismidir.
Örnek: Code:
<?php
// resim handlerini oluşturuyoruz
$resim=imagecreatefromjpg("resim.jpg");
// elde edilen resource tipindeki veriyi
// XPM verisi elde edecek fonksiyona veriyoruz
$xpmdata=image2xpm_d($resim);
// işimiz bitincede resimin hafızadan silinmesini sağlıyoruz
imagedestroy($resim);
// XPM verisini dosyaya yazıyoruz
xpmd_2file($xpmdata,"resim");
// böylece resim.jpg yeniden çevirme işlemine tabi tutmadan
// kullanma imkanına kavuşmuş oluyoruz.
list($pixmap,$mask)=gdk::pixmap_create_from_xpm("resim.xpm");
XPM harici resim formatlarının PHP-Gtk ile kullanımını anlatmaya çalıştığım bu yazının sonunda, PHP-Gtk 2 içerisinde bukadar karmaşaya gerek kalmadan direkt olarak farklı resim resim formatlarını hatta animasyon kullanabileceğimizi müjdeleyerek bitirmek istiyorum. PHP-Gtk 2 ye ilişkin dökümantasyon (henüz) olmadığı için bu konuyla ilgili ayrıntılı bilgiyi şimdilik veremiyorum.
fix-img kütüphane kodları:
Code:
<?php
<?php
/**
* @author Jonathan Gotti <nathan at the-ring dot homelinux dot net>
* @copyleft (l) 2003-2004 Jonathan Gotti
* @package processing
* @subpackage FX-img
* @license http://opensource.org/licenses/gpl-license.php GNU Public
* License
*/
/**
* xpm resizing (nearest neighbour method)
* @param mixed $xpmsource string path to xpm file or array xpm data
* @param int $w_out the width output
* @param int $h_out the height output
* @return xpmdatas
*/
function xpm_resize($xpmsource,$w_out,$h_out,$progress=null ){
# check correct size input
settype($w_out,'int'); settype($h_out,'int');
if( $w_out<=0 || $h_out<=0) return FALSE;
# Check input type
if(!is_array($xpmsource)){
if(! $xpmsource = xpm2xpm_d($xpmsource))
return FALSE;
}
# get xpmdatas infos
if(! preg_match("!(\d+)\s+(\d+)\s+(\d+)\s+(\d+)!",$xpmsource[0],$m))
return FALSE;
$w_in = $m[1];
$h_in = $m[2];
$col_nb = $m[3];
$col_chr= $m[4];
#copy data headers
$out[0] = "$w_out\t$h_out\t$col_nb\t$col_chr";
# retrieve indexed palette
if($progress){
$progress->set_format_string('read palette');
gtkgui_refresh();
}
for($i=1;$i<=$col_nb;$i++){
if(preg_match("!(.{".$col_chr."})\s+c\s+#([0-9a-f]{6}|none)!i",
$xpmsource[$i],$mcol))
$palette[$mcol[1]]=$mcol[2];
else
$palette[str_repeat('~',$col_chr)]='None';
# if we can't retrieve the color value we forced it to none
#copy palette to new datas
$out[$i] = $xpmsource[$i];
if($progress){
$progress->set_percentage(($i)/$col_nb);
gtkgui_refresh();
}
}
$colorids = array_flip($palette);
#Now resizing
$w_ratio = $w_in/$w_out;
$h_ratio = $h_in/$h_out;
if($progress){
$progress->set_format_string('resizing');
gtkgui_refresh();
}
for($i=0;$i<$w_out;$i++){ # for each output row
$x_src = intval($i*$w_ratio);
for($y=0;$y<=$h_out;$y++){ # for each output column
$y_src = intval($y*$h_ratio);
$out[$y+($col_nb+1)] .= substr($xpmsource[$y_src+($col_nb+1)],
$col_chr*$x_src,$col_chr);
}
if($progress){
$progress->set_percentage($i/$w_out);
gtkgui_refresh();
}
}
return $out;
}
/*
* return an xpm data array from a xpm file
* @param string $file path to the xpm file
* @return array() xpm datas (FALSE on error)
*/
function xpm2xpm_d($file){
if(! $array = file($file))
return FALSE;
# reading and formating xpmdata
foreach($array as $lineid=>$line){
if(! $started){
if(! preg_match("!\"\d+\s+\d+\s+\d+\s+\d+\",!",$line) )
#detect the first interesting line
continue;
$array[$lineid] = preg_replace("![\",\n]!","",$line);
$started = TRUE;
# bool value to know if we've start or not to format xpmdata
$startline = $lineid;
}else{ # format xpm datas
$array[$lineid] = preg_replace("!^\s*\"([^\"]+)\"\s*,\s*$!","\\1",$line);
if(preg_match("!(\"([^\"]+)\")?\s*}\s*;!",$line,$m)){ # is this the end
if(!$m[2]){
$endline = $lineid-1;
}else{
$array[$lineid] = $m[2];
$endline = $lineid;
}
}
}
}
# clean array
while(count($array)>$endline+1)array_pop($array);
# delete eventually un-needed end
for($i=0;$i<$startline;$i++)array_shift($array);
# delete xpm headers
return $array;
}
/**
* return the size of a xpm file or data
* @param mixed $xpm (string filename or xpmdata array)
* @return array(width,height)
*/
function xpm_getsize($xpm){
if(is_file($xpm)){
if(! ($xpm = fopen($xpm,'r')) )
return FALSE;
while($line = fread($xpm,4096)){
if(preg_match("!(\d+)\s+(\d+)\s+\d+\s+\d+!",$line,$m))
break;
}
}elseif(is_array($xpm)){
if(! preg_match("!(\d+)\s+(\d+)\s+\d+\s+\d+!",$xpm[0],$m))
return FALSE;
}
if(! count($m)==3)
return FALSE;
array_shift($m);
return $m;
}
/**
* get the image palette
* @author
jonathan.gotti@free.fr
* @date 2003-12-20
* @param ressource image $img
* @return array
*/
function imagegetpalette($img){
# echo imagecolorstotal($img)."colors found\n";
$width = imagesx($img);
$height= imagesy($img);
//try an alternate method since the image is a paletted image
//better 5 or 6 seconds on a 1280x1024 png 256clrs
for($i=0;$i<imagecolorstotal($img);$i++){
$colors[$i]=imagecolorsforindex($img,$i);
}
return $colors;
}
/**
* get a xpm style palette from a gd one
* @author
jonathan.gotti@free.fr
* @date 2003-12-20
* @param array $gdpalette
* @param string $indexed_type 'gd' keep the gd_index,'xpm' indexed
* by xpm char code
* @param string $value_type 'char_code' the xpm char code index,
* 'color' the xpm color value,'both' associated value is are array containing
* xpm char code and xpm color value
* @param array $trans array of transparent color values
* @return array
*/
function gd2xpmpalette($gdpalette,$indexed_type='xpm',
$value_type='color',$trans=null){
if($GLOBALS['VERBOSE'])
echo "transform to xpm palette \n";
$nb_colors = count($gdpalette);
if($indexed_type=='xpm' || $value_type!='color'){
//initialize char array if needed
$first_char = 48;//lowest used ASCII char code
$last_char = 126;//highest used ASCII char code
$nb_char = intval(log($nb_colors)/log($last_char-$first_char))+1;
//Thanks to my friend RHONONO for this one
for($i=0;$i<=$nb_char;$i++){//initialize array of char
$chars[$i]=$first_char;
}
}
foreach($gdpalette as $gdindex => $gdcolor){
if($indexed_type=='xpm' || $value_type!='color'){
//recompose xpm character coding only if needed
$char_code = null;//initialise char_code
for($i=0;$i<$nb_char;$i++){//increment other chars
$chars[0]++;//increment chars
if($chars[$i]>$last_char){//check chars are in the good range
$chars[$i]=$first_char;
$chars[$i+1]++;
}
$char_code = chr(($chars[$i]==92?47:$chars[$i])) . $char_code ;
}
}
if($indexed_type == 'xpm')//choose indexed type
$outindex = $char_code;
else//assume gd indexed wanted
$outindex = $gdindex;
//the val acoording to it
switch($value_type){
case 'color':
if($gdcolor['alpha']>=127)
$out[$outindex] = 'None';
else
$out[$outindex] = strtoupper('#'.str_pad(dechex($gdcolor['red']),2,
'0',STR_PAD_LEFT).str_pad(dechex($gdcolor['green'])
,2,'0',STR_PAD_LEFT).str_pad(dechex($gdcolor['blue']),2,'0',STR_PAD_LEFT));
break;
case 'char_code':
$out[$outindex] = $char_code;
break;
case 'both':
if($gdcolor['alpha']>=127)
$out[$outindex] = array(0=>$char_code,1=>'None');
else
$out[$outindex] = array( 0=>$char_code,1=>strtoupper(
'#'.str_pad(dechex($gdcolor['red']),2,'0',STR_PAD_LEFT)
.str_pad(dechex($gdcolor['green']),2,'0',STR_PAD_LEFT).str_pad(
dechex($gdcolor['blue']),2,'0'
,STR_PAD_LEFT)));
break;
}
}
return $out;
}
/**
* get xpm_data from gd image resource
* @date 2003-12-20
* @param resource gd image $img
* @return xpm data
* @param gtkprogress &$progress is an optional progressbar to trace
* activity (will received a value between 0 to 100)
* @uses gtkgui_refresh, imagegetpalette, gd2xpmpalette,
*/
function image2xpm_d($img,$trans=TRUE,$progress=null){
# print_r($progress->adj);
$exectime_start=get_microtime();
if($GLOBALS['VERBOSE'])
echo "recomposing xpm data \n";
$w = imagesx($img);
$h = imagesy($img);
if(imageistruecolor($img) && $trans){
if($progress){
$progress->set_format_string('keep transparency');
gtkgui_refresh();
}
$imgtmp = imagecreatetruecolor($w,$h);
//creation d'une copie de l'image en mode palette
imagealphablending($imgtmp,FALSE);
# imagecopymerge($imgtmp,$img,0,0,0,0,$w,$h,100);
//pour en recuperer la palette
imagecopymerge($imgtmp,$img,0,0,0,0,$w,$h,100);
//pour en recuperer la palette
imagetruecolortopalette($imgtmp,TRUE,255);
$transindex = imagecolorallocate($imgtmp,1,1,1);
//set the trans color to a known one
$transindex = imagecolortransparent($imgtmp,$transindex);
if($progress){
$progress->set_format_string('read palette');
gtkgui_refresh();
}
$gdpalette = imagegetpalette($imgtmp);
if($progress){
$progress->set_format_string('XPMize palette');
gtkgui_refresh();
}
$palette = gd2xpmpalette($gdpalette,'gd','both');
list($color0k,$color0v )= each($palette);
$xpm_d[0]= "$w $h ".count($palette)." ".strlen($color0v[0]);//image definition
if($progress){
$progress->set_format_string('format palette');
gtkgui_refresh();
}
foreach($palette as $color){ //recompose palette_data
$xpm_d[]=$color[0]." c ".$color[1];
}
if($progress){
$progress->set_format_string('recomposing image');
gtkgui_refresh();
}
for($y=0;$y<$h;$y++){//recompose image
$row = null;
for($x=0;$x<$w;$x++){
$color = imagecolorsforindex($img,imagecolorat($img,$x,$y)) ;
//verifie la transparence sur l'image d'origine
$index = imagecolorat($imgtmp,$x,$y);
//recupere l'index de la couleur ds la copie qui
//nous a donné la palette
if($color['alpha']>126)
$row .= $palette[$transindex][0];
else
$row .= $palette[$index][0];
}
if($progress){
$progress->set_percentage(($y+1)/$h);
gtkgui_refresh();
}
$xpm_d[]=$row;
}
}else{
if(imageistruecolor($img))
imagetruecolortopalette($img,TRUE,255);
if($progress){
$progress->set_format_string('read palette');
gtkgui_refresh();
}
$gdpalette = imagegetpalette($img);
if($progress){
$progress->set_format_string('XPMize palette');
gtkgui_refresh();
}
$palette = gd2xpmpalette($gdpalette,'gd','both');
list($color0k,$color0v )= each($palette);
$xpm_d[0]= "$w $h ".count($palette)." ".strlen($color0v[0]);//image definition
if($progress){
$progress->set_format_string('format palette');
gtkgui_refresh();
}
$palette_num = count($palette);
foreach($palette as $color){//recompose palette_data
$xpm_d[]=$color[0]." c ".$color[1];
if($progress){
$progress->set_percentage(++$i/$palette_num);
gtkgui_refresh();
}
}
if($progress){
$progress->set_format_string('recomposing image');
gtkgui_refresh();
}
for($y=0;$y<$h;$y++){//recompose image
$row = null;
for($x=0;$x<$w;$x++){
$row .= $palette[imagecolorat($img,$x,$y)][0];
}
$xpm_d[]=$row;
if($progress){
$progress->set_percentage(($y+1)/$h);
gtkgui_refresh();
}
}
}
if(isset($imgtmp))
imagedestroy($imgtmp);
return $xpm_d;
}
/**
* write an xpm file from xpm data
* @author
jonathan.gotti@free.fr
* @date 2003-12-20
* @param array $xpm_d
* @param string $file
* @return bool
*/
function xpm_d2file($xpm_d,$file){
if($GLOBALS['VERBOSE'])
echo "write $file\n";
if(! $f = @fopen($file,'w'))
return FALSE;
fputs($f,"/* XPM */\nstatic char * ".basename($file)."[] = {\n");
foreach($xpm_d as $k => $row){
foreach ($row as $dt=>$nrow){
fputs($f,"\"$nrow\",");
fputs($f,"\n"); }
}
$pos = ftell($f);
fputs($f,"};");
fclose($f);
return TRUE;
}
function get_microtime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
?>