Je jina funkce, ktera je rychlejsi nez imagecolorat($img, $i, $j); ?
Totiz, mam obrazek 1000x1000 a script mi pres colorat jede asi 3.5s! To je pro php 5.5 lokalne celkem neprijatelny vysledek. Nechci ale externi program jako imagemagic.
Fórum › PHP
Php imagecolorat - prilis pomale
![](img/forum_vlakno_help_vyreseno.png)
Je mi to jasne, ze je rychlejsi nasel jsem prispevky odkazujici na nej. Ale nechci pouzivat externi program. Jedna se jen o testovaci aplikaci. Pro realne pouziti bych si asi napsal vlastni funkci.
Ja jen neco zkousim.
Ted jsem zachytil clanek o ImageZero lossless kompresi. Napadlo mne, ze, co asi resi a skryvaji. Dyt je to jasne. Pokud je obrazek hodne velky, tak nejblizsi pixely jsou stejne, takze muzou delat prosty rozdil pixelu a pak to zkodovat do hufmana nebo gzip, treba. Nemusi vubec resit pole 8x8 jak to dela jpeg. V pripade skoro stejnych pixelu je rozdil sousednich +-5, obvykle. Takze cela data se scvrknou na nekolik velkych rozdilu + (cisla 0,1,2,3,4 a 255,243,253,252,251). No, kazdopadne to bude uzasne rychle pro kompresi i dekompresi proti matrixovani pres 8x8. Chtel jsem zkusit, jestli dam pomer asi jako ten ImageZero.
Plus minus mi ted vychazi, ze obrazek,
50k jpeg ztratove komprimovany pres dct, odstiny sede, 426400 byte-pixelu
gzip 217682
pocet znaku prvnich 16 ku zbytku je 383652 / 42748 (ale pocita to 3.5s)
- Hufmana, kdyz si nastavis pul na pul, 1 bit na je to prvnich 16 a neni, tak mas 5*383652 + 9*42748 bitu (2302992/8) = 287874
- Huff na 0-14 4 bity, 15 jako 4+8 bity pro ostatni, tak mas priblizne 4*383652 + 12*42748 = 2047584 (/8 = 255948)
priblizne*, protoze bych musel prepocitat znoby pomer pro 0-15 a 16-255, ale kolem 16 uz se to meni tak malo, ze je to jiste skoro stejne
- a kdyz si ho nastavis nejak optimalnej, tak to urcite pujde jeste niz.
256/426 vuci bmp je to asi 60% huff
218/426 = 52% gzip
<?php
ini_set('max_execution_time', 10000); //10000s
set_time_limit(10000);
ini_set('memory_limit', '256M');
function microtime_float() //pp 17.3.2014
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time = array();
$time[] = microtime_float();
function timePrint($time)
{
$time[] = microtime_float();
$t = array();
$t[] = round($time[count($time)-1]-$time[0],3);
for ($i=1;$i<count($time);$i++)
{
$t[] = round($time[$i]-$time[$i-1],3);
}
$t = implode(" | ",$t);
echo '<hr>Cas zpracovani '.$t.' s';
}
function transf(&$img,$w,$h)
{
$out = '';
$tmp = array(0,0,0);
$z = array(0,0,0);
$tmp = 0;
$tbl = array();
$code = array();
$n = 256;
$char_count = array();
for ($i=0,$j=-$n;$i<$n;++$i,++$j)
{
$tbl[$j] = chr($i);
$tbl[$i] = chr($i);
$code[$j] = $i;
$code[$i] = $i;
$char_count[$i] = 0;
}
ksort($tbl);
$k=0;
for ($j=0;$j<$h;++$j)
{
for ($i=0;$i<$w;++$i)
{
$rgba = imagecolorat($img, $i, $j);
$b = $rgba & 0xFF;
//echo ($code[$b-$tmp]).", ";
$out .= $tbl[$b-$tmp];
++$char_count[$code[$b-$tmp]];
// $tmp = $rgba;
$tmp = $b;
++$k;
}
//if ($j>1) break;
}
echo '<br>k1 =='.$k.' == ';
rsort($char_count);
$a = 0; $b=0; for ($i=0;$i<256;++$i) {if ($i>16) {$b+=$char_count[$i];} else {$a+=$char_count[$i];}}
echo " 16: ".$a ." / ".$b;
return $out;
}
$tbl_zigzag = //peter jpeg
array(
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
);
function ReZigZag($inp,$zigzag)
{
$out = array();
$i=0;
for($i=0; $i<64; ++$i)
{
$out[$zigzag[$i]] = $inp[$i];
}
return $out;
}
function ZigZag($inp,$zigzag)
{
$out = array();
$i=0;
for($i=0; $i<64; ++$i)
{
$out[$i] = $inp[$zigzag[$i]];
}
return $out;
}
function transf2($img,$w,$h) //2 + zigzag
{
$out = '';
$tmp = array(0,0,0);
$z = array(0,0,0);
$tmp = 0;
$tbl = array();
$code = array();
$n = 256;
for ($i=0,$j=-$n;$i<$n;++$i,++$j)
{
$tbl[$j] = chr($i);
$tbl[$i] = chr($i);
$code[$j] = $i;
$code[$i] = $i;
}
ksort($tbl);
$k=0;
for ($j=0;$j<$h;$j+=8)
{
for ($i=0;$i<$w;$i+=8)
{
for ($s=0;$s<8 && $j+$s<$h;$s+=1)
{
for ($r=0;$r<8 && $i+$r<$w;$r+=1)
{
$rgba = imagecolorat($img, $i+$r, $j+$s);
$b = $rgba & 0xFF;
//echo ($code[$b-$tmp]).", ";
$out .= $tbl[$b-$tmp];
// $tmp = $rgba;
$tmp = $b;
++$k;
}
}
}
//if ($j>1) break;
}
echo '=='.$k.' ==';
return $out;
}
function transf3($img,$w,$h)
{
global $tbl_zigzag;
$out = '';
$tmp = array(0,0,0);
$z = array(0,0,0);
$tmp = 0;
$tbl = array();
$code = array();
$arr = array();
$n = 256;
for ($i=0,$j=-$n;$i<$n;++$i,++$j)
{
$tbl[$j] = chr($i);
$tbl[$i] = chr($i);
$code[$j] = $i;
$code[$i] = $i;
}
ksort($tbl);
$k=0;
for ($j=0;$j<$h;$j+=8)
{
for ($i=0;$i<$w;$i+=8)
{
$n = 0;
for ($s=0;$s<8 && $j+$s<$h;$s+=1)
{
for ($r=0;$r<8 && $i+$r<$w;$r+=1)
{
$rgba = imagecolorat($img, $i+$r, $j+$s);
$arr[$n] = $rgba & 0xFF;
++$n;
++$k;
}
}
//print_r($arr);
$arr = Zigzag($arr,$tbl_zigzag);
//print_r($arr);
$n = 0;
for ($s=0;$s<8 && $j+$s<$h;$s+=1)
{
for ($r=0;$r<8 && $i+$r<$w;$r+=1)
{
//echo ($code[$arr[$n]-$tmp]).", ";
$out .= $tbl[$arr[$n]-$tmp];
$tmp = $arr[$n];
++$n;
}
}
}
//if ($j>1) break;
}
echo '=='.$k.' ==';
return $out;
}
function transf4($img,$w,$h)
{
global $tbl_zigzag;
$out = '';
$tmp = array(0,0,0);
$z = array(0,0,0);
$tmp = 0;
$tbl = array();
$code = array();
$arr = array();
$n = 256;
for ($i=0,$j=-$n;$i<$n;++$i,++$j)
{
$tbl[$j] = chr($i);
$tbl[$i] = chr($i);
$code[$j] = $i;
$code[$i] = $i;
}
ksort($tbl);
$k=0;
for ($j=0;$j<$h;$j+=8)
{
for ($i=0;$i<$w;$i+=8)
{
$n = 0;
$tmp = 0;
for ($s=0;$s<8 && $j+$s<$h;$s+=1)
{
for ($r=0;$r<8 && $i+$r<$w;$r+=1)
{
$rgba = imagecolorat($img, $i+$r, $j+$s);
$arr[$n] = $rgba & 0xFF;
$tmp+= $arr[$n];
++$n;
++$k;
}
}
//echo '<br>x'.$tmp;
$tmp = $tmp>>6;
//print_r($arr);
$arr = Zigzag($arr,$tbl_zigzag);
//if (!isset($tbl[$tmp])) echo '<br>'.$tmp.'<br>';
//else{
$out .= $tbl[$tmp];
//print_r($arr);
$n = 0;
for ($s=0;$s<8 && $j+$s<$h;$s+=1)
{
//echo ($code[$arr[$n]-$tmp]).", ";
for ($r=1;$r<8 && $i+$r<$w;$r+=1)
{
echo ($code[$arr[$n]-$tmp]).", ";
$out .= $tbl[$arr[$n]-$tmp];
// $tmp = $arr[$n];
++$n;
}
}
//}
}
if ($j>1) break;
}
echo '=='.$k.' ==';
return $out;
}
function transf5($img,$w,$h) //2 + zigzag
{
$out = '';
$tmp = array(0,0,0);
$z = array(0,0,0);
$tmp = 0;
$tbl = array();
$code = array();
$n = 256;
$char_count = array();
for ($i=0,$j=-$n;$i<$n;++$i,++$j)
{
$tbl[$j] = chr($i);
$tbl[$i] = chr($i);
$code[$j] = $i;
$code[$i] = $i;
$char_count[$i] = 0;
}
ksort($tbl);
$k=0;
$b=0;
$r=0;
$s=0;
$si = 8;
$sj = 8;
for ($j=0;$j<$h;$j+=$sj)
{
for ($i=0;$i<$w;$i+=$si)
{
$rgba = imagecolorat($img, $i, $j);
$b = $rgba & 0xFF; // staci red barva
$out .= $tbl[$b-$tmp];
++$char_count[$code[$b-$tmp]];
$tmp = $b;
++$k;
//echo ($code[$tmp]).", ";
for ($s=0;$s<$sj && $j+$s<$h;++$s)
{
for ($r=0;$r<$si && $i+$r<$w;++$r)
{
$rgba = imagecolorat($img, $i+$r, $j+$s);
$b = $rgba & 0xFF; // staci red barva
//echo ($code[$b-$tmp]).", ";
if ($r>0 || $s>0)
{
$out .= $tbl[$b-$tmp];
//echo ($code[$b-$tmp]).", ";
++$k;
++$char_count[$code[$b-$tmp]];
}
}
//echo $k.' ';
}
//echo $k.' ';
}
//if ($j>1) break;
//if ($k>300) break;
}
echo '<br>k5 =='.$k.' == ';
rsort($char_count);
$a = 0; $b=0; for ($i=0;$i<256;++$i) {if ($i>32) {$b+=$char_count[$i];} else {$a+=$char_count[$i];}}
echo " 32: ".$a ." / ".$b;
return $out;
}
$name1 = "img/jp-bwgirl.jpeg"; //
//$name1 = "img/jp-bwgirl-2.jpeg"; //
$name2 = "tmp/xxx"; //
$bool = file_exists($name1);
echo 'Soubor '. ($bool ? 'existuje' : 'chyba neexistuje').'<br>';
$b = filesize($name1);
$img = imagecreatefromjpeg($name1);
$w = imagesx($img);
$h = imagesy($img);
$out = '';
$out2 ='';
$out3 = '';
$out4 = '';
$out5 = '';
$out = transf($img,$w,$h);
//$out2 = transf2($img,$w,$h);
//$out3 = transf3($img,$w,$h);
//$out4 = transf4($img,$w,$h);
$out5 = transf5($img,$w,$h);
imagedestroy($img);
/*
$file2 = fopen($name2, "wb");
fwrite($file2,$out);
fclose($file2);
*/
$a=0; $a2=0; $a3=0; $a4=0; $a5=0;
$out = gzcompress($out,9); $a = strlen($out); unset($out);
//$out2 = gzcompress($out2,9); $a2 = strlen($out2); unset($out2);
//$out3 = gzcompress($out3,9); $a3 = strlen($out3); unset($out3);
//$out4 = gzcompress($out4,9); $a4 = strlen($out4); unset($out4);
$out5 = gzcompress($out5,9); $a5 = strlen($out5); unset($out5);
echo '<br>out / in = floor(10000*$a/$b)/100 % gzip';
echo '<br>'.$a. ' / '. $b .' = '.(floor(10000*$a/$b)/100).'% gzip';
echo '<br>'.$a2. ' / '. $b .' = '.(floor(10000*$a2/$b)/100).'% gzip';
echo '<br>'.$a3. ' / '. $b .' = '.(floor(10000*$a3/$b)/100).'% gzip';
echo '<br>'.$a4. ' / '. $b .' = '.(floor(10000*$a4/$b)/100).'% gzip';
echo '<br>'.$a5. ' / '. $b .' = '.(floor(10000*$a5/$b)/100).'% gzip';
echo '<br>'.$w. ' x '. $h .' = '.($w * $h) .'... musi se shodovat s k';
timePrint($time);
?>
<?php
// $code[$j] = $i;
// $code[$i] = $i;
//foreach($tbl as $i=>$j) echo ",".$i.":".$j; return ;
//var_dump($rgba);
// $r = ($rgba >> 16) & 0xFF;
// $g = ($rgba >> 8) & 0xFF;
//var_dump($b);
//echo $r.",".$g.",".$b.", ";
// for ($k=0;$k<3;++$k)
// {
// $z[$k] = $rgba[$k]-$tmp[$k];
// $z[$k] += $z[$k]<0 ? 256 : 0;
// $out .= $tbl[$z[$k]];
// $out .= $tbl[$rgba[$k]-$tmp[$k]];
//echo $rgba[$k].", ";
// $out .= $tbl[$rgba[$k]];
// }
// $out .= $tbl[$r];
// $out .= $tbl[$g];
// $out .= $tbl[$b];
// $out .= 'b';
//$out .= $tbl[$b];
//echo ($code[$b-$tmp]).", ";
?>
Kdyby mel nekdo chut si hrat se source-code...
Tak, muzu dat i zjednodusenou verzi a pro RGB (v komentu pokus pro imagemagic, uprava +-n na +n, upvrava pokus o prepsani funkci chr; ale on chce na prepis funkci a imagemagick instalovat cosi, coz se mi nechce).
1920x1200 rgb, zpracovano za 23s, komprese gzip 40/69 = 58%
<?php
ini_set('max_execution_time', 10000); //10000s
set_time_limit(10000);
ini_set('memory_limit', '256M');
function microtime_float() //pp 17.3.2014
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time = array();
$time[] = microtime_float();
function timePrint($time)
{
$time[] = microtime_float();
$t = array();
$t[] = round($time[count($time)-1]-$time[0],3);
for ($i=1;$i<count($time);$i++)
{
$t[] = round($time[$i]-$time[$i-1],3);
}
$t = implode(" | ",$t);
echo '<hr>Cas zpracovani '.$t.' s';
}
function transf(&$img,$w,$h)//&$imagick
{
$out = array('','','');
$c = array(0,0,0);
$tmp = array(0,0,0);
$tbl = array();
$n = 256;
$nn = $n>>1;
$m = 0;
for ($i=0,$j=-$n;$i<$n;++$i,++$j)
{
$tbl[$j] = chr($i);
$tbl[$i] = chr($i);
/*
$m = $i<$nn ? $i : $n-1-$i;
$tbl[$j] = chr($m);
$tbl[$i] = chr($m);
*/
}
ksort($tbl);
//$a = 0;
//$iterator = $imagick->getPixelIterator();
$pixel = 0;
for ($j=0;$j<$h;++$j)
{
for ($i=0;$i<$w;++$i)
{
$pixel = imagecolorat($img, $i, $j);
//return '';
$c[2] = $pixel & 0xFF;
$c[1] = ($pixel >> 8) & 0xFF;
$c[0] = ($pixel >> 16) & 0xFF;
$out[0] .= $tbl[$c[0]-$tmp[0]];
$out[1] .= $tbl[$c[1]-$tmp[1]];
$out[2] .= $tbl[$c[2]-$tmp[2]];
$tmp[0] = $c[0];
$tmp[1] = $c[1];
$tmp[2] = $c[2];
}
}
/*
for ($j=0;$j<$h;++$j)
{
for ($i=0;$i<$w;++$i)
{
$pixel = imagecolorat($img, $i, $j);
foreach($iterator as $row => $pixels)
{
foreach ($pixels as $column => $pixel)
{
var_dump($pixel);
$iterator->syncIterator();
return '';
*/
return $out[0].$out[1].$out[2];
}
/*
<?php
$imagick = new Imagick("my_image.jpeg");
$iterator = $imagick->getPixelIterator();
foreach($iterator as $row => $pixels) {
foreach ($pixels as $column => $pixel) {
// Do something with $pixel
}
$iterator->syncIterator();
}
?>
*/
$name1 = "img/jp-bwgirl.jpeg"; //
$name1 = "img/tropical-island-hut.jpg"; //
//$name1 = "img/jp-bwgirl-2.jpeg"; //
$name2 = "tmp/xxx"; //
$bool = file_exists($name1);
echo 'Soubor '.$name1.' '. ($bool ? 'existuje' : 'chyba neexistuje').'<br>';
$b = filesize($name1);
$img = imagecreatefromjpeg($name1);
$w = imagesx($img);
$h = imagesy($img);
//$imagick = new Imagick($name1);
//$w = $imagick->getImageWidth();
//$h = $imagick->getImageHeight();
//var_dump($img);
//imagexbm($img, 'simpletext.xbm');
//header('Content-Type: image/vnd.wap.wbmp');
//imagewbmp($img,$name2);
////header('Content-Type: ' . image_type_to_mime_type(IMAGETYPE_WBMP));
////image2wbmp($img);
$b = $w*$h*3;
$out = '';
$out = transf($img,$w,$h);
imagedestroy($img);
$a = 0;
$out = gzcompress($out,9);
$file2 = fopen($name2, "wb");
fwrite($file2,$out);
fclose($file2);
$a = strlen($out); unset($out);
echo '<br>out / in = floor(10000*$a/$b)/100 % gzip';
echo '<br>'.$a. ' / '. $b .' = '.(floor(10000*$a/$b)/100).'% gzip';
echo '<br>'.$w. ' x '. $h .' = '.($w * $h);
timePrint($time);
/*
class charCode
{
private $a, $b;
function __construct()
{
$this->a = array();
$this->b = array();
for($i=0;$i<256;++$i)
{
$this->a[$i] = chr($i);
$this->b[chr($i)] = $i;
}
}
function chr($code)
{return $this->b[$code];}
function ord($char)
{return $this->a[$char];}
}
$charcode = new charCode();
//rename_function('strlen', 'new_strlen');
//override_function('chr', '$code', 'return $charcode->chr($code);');
//override_function('ord', '$char', 'return $charcode->ord($char);');
runkit_function_redefine('chr', '$code', 'return $charcode->chr($code);');
runkit_function_redefine('ord', '$char', 'return $charcode->ord($char);');
*/
?>
![](img/forum_nove_psp_new.png)
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
![](/img/smile/1.gif)
![](/img/smile/2.gif)
![](/img/smile/3.gif)
![](/img/smile/4.gif)
![](/img/smile/5.gif)
![](/img/smile/6.gif)
![](/img/smile/7.gif)
![](/img/smile/8.gif)
![](/img/smile/9.gif)
![](/img/smile/10.gif)
![](/img/smile/11.gif)
![](/img/smile/12.gif)
![](/img/smile/13.gif)
![](/img/smile/14.gif)
![](/img/smile/15.gif)
![](/img/smile/16.gif)
![](/img/smile/17.gif)
![](/img/smile/18.gif)
![](/img/smile/19.gif)
![](/img/smile/20.gif)
![](/img/smile/21.gif)
![](/img/smile/22.gif)
![](/img/smile/23.gif)
![](/img/smile/24.gif)
![](/img/smile/25.gif)
![](/img/smile/26.gif)
![](/img/smile/27.gif)
![](/img/smile/28.gif)
![](/img/smile/29.gif)
![](/img/smile/30.gif)
![](/img/smile/31.gif)
![](/img/smile/32.gif)
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Příliš agresivní UAC? — založil marpit
Príliš dlhý názov súboru — založil lukas.balaz
Příliš velký sql soubor — založil pavel3
.htaccess vás presmeroval príliš veľakrát. — založil zelenac1
Prosim pomoc, sql dotaz trva prilis dlouho — založil Gibon
Moderátoři diskuze