Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: Martin Šácha 10 Května 2010, 15:04:38
-
Zdravím, netýká se to přímo linuxu, ale web k linuxu patří takže je určitá pravděpodobnost že to někdo ví. :) Mám problém (pravděpodobně) s funkcí imageline(), nevykresluje totiž do obrázku čáry když ji použiju více než 255krát.
Zdroják:
<?php
if(isset($_GET["vstup"]))
{
$vstup = $_GET["vstup"];
$retez="";
for($i=0;$i<strlen($vstup);$i++)
{
$retez=$retez . sha1(md5(substr($vstup,$i,1)));
//printf("%s<br>",$retez);
}
//echo strlen($retez) . "<br>";
header("Content-type: image/png");
$vyska=40;
$sirka=strlen($vstup);
$obrazek=imagecreate($sirka,$vyska);
$str_ind=0;
imagesetthickness($obrazek,1);
for($y=0;$y<40;$y++)
{
for($x=0;$x<$sirka;$x++)
{
$znak=hexdec(substr($retez,$str_ind,1))*10;
//printf("%s, %d", $znak, $znak);
//printf("str_ind %d cislo: %d znak %s x %d y %d<br>",$str_ind,$znak,substr($retez,$str_ind,1), $x, $y);
$barva=imagecolorallocate($obrazek,$znak,$znak,$znak);
imageline($obrazek,$x,$y,$x,$y,$barva);
$str_ind++;
}
}
}
imagepng($obrazek);
imagedestroy($obrazek);
?>
Ještě přikládám příklad výstupu, je jasně vidět od kterého pixelu (čtvrtý řádek odspoda) fce imageline() přestává pracovat.
Jedná se o PHP 5.3.2 (default na Lucidu)
[attachment deleted by admin]
-
co jinou funkci?
-
Bohužel imagesetpixel() selže na stejném místě taky. :(
-
Tak to je asi nějakým způsobem omezené...
-
No právě, ale jakým.
Googlil jsem fráze typu "imagesetpixel 255 bug problem", "imageline 255 problem with php5" atd... ale bez výsledku. Pár nahlášených bugů to našlo, ale byly úplně o něčem jiném.
-
Můžete prosím někdo ten script vyzkoušet u sebe? Docela mě to chování zajímá a na nic jsem nepřišel.
-
<?php
header("Content-type: image/png");
$vyska=500;
$sirka=500;
$obrazek=imagecreate($sirka,$vyska); //spatne
//$obrazek=imagecreatetruecolor($sirka,$vyska); //dobre
$white=imagecolorallocate($obrazek,255,255,255);
for($a=0; $a<=4000; $a++) {
$c[] = imagecolorallocate($obrazek,mt_rand(0, 255),mt_rand(0, 255),mt_rand(0, 255));
}
$i = 0;
for($y=0;$y<$vyska;$y++) {
for($x=0;$x<$sirka;$x++) {
imageline($obrazek,$x,$y,$x,$y,$c[mt_rand(0, 4000)]);
$i++;
}
}
imagepng($obrazek);
imagedestroy($obrazek);
?>
EDIT: došel Vám počet povolených barev na typu vytvořeného obrázku. fix -> použití True Color obrázku.
http://php.net/manual/en/function.imagecreatetruecolor.php (http://php.net/manual/en/function.imagecreatetruecolor.php)
Hodně štěstí při dalším vývoji :-)
-
Wow, díky už to funguje, to s výměnou inicializační fce mi došlo, nebojte se :)
Možná trošku nejasnost - jak jsem mohl překročit počet barev, když jsem byl v monochromu (0 - 160, ekvivalent 0-F v hex. soustavě) se skokem 10, tj pouze 16 barev?
-
to s výměnou inicializační fce mi došlo, nebojte se
Nepodceňuji Vás, ale pokud přijde někdo jiný s podobným problémem a bude zde vyhledávat tak je lepší když je to tam přímo napsáno a link se taky hodí ;).
Možná trošku nejasnost - jak jsem mohl překročit počet barev, když jsem byl v monochromu (0 - 160, ekvivalent 0-F v hex. soustavě) se skokem 10, tj pouze 16 barev?
Zdrojové kódy funkce neznám (Mám rád black-boxy :-D hlavní je vědět co dát dovnitř a co jde ven :-D :-D). Pravděpodobné vysvětlení je: že je určitě jednodušší (rychlejší, efektivnější, méně náročné na zdroje) vytvořit vnitřní počítadlo (proměnou) a tu inkrementovat. Než ukládat a následné vyhledávat ve všech předchozích datech. Vy sice nemáte tolik barev, ale jednu určitou barvu voláte vícekrát (tj vícenásobný inkrement na jedné barvě), tímhle pěkně plácáte se zdroji. Protože víte jaké barvy budete mít můžete si je na generovat dopředu (podobně jako v mé ukázce, sice se mi asi taky opakují ale co :-D) 16 volání funkce a 256+ je sakra rozdíl :-D, tím se vám zrychlí běh skriptu (to poznáte v zatíženém prostředí).
Navíc bych tipoval, že když na vstup vložíte dostatečně dlouhý řetězec, tak se Vám problém bude opakovat a to již neopravíte jinak než optimalizací viz výše. S trochou štěstí by to číslo mohlo být dost vysoké 2^24 (tedy opravdu truecolor) případně plný int 2^32 respektivě 2^64 v závislosti na platformě.
-
Navíc bych tipoval, že když na vstup vložíte dostatečně dlouhý řetězec, tak se Vám problém bude opakovat a to již neopravíte jinak než optimalizací viz výše. S trochou štěstí by to číslo mohlo být dost vysoké 2^24 (tedy opravdu truecolor) případně plný int 2^32 respektivě 2^64 v závislosti na platformě.
Délka řetězce je strlen(vstup)*40, takže tam by problém být neměl. Platforma je díkybohu 64bitová, popravdě v rozsahu 64integeru by mě problém nikdy nenapadlo hledat :D
Ale máte pravdu že využít pole by bylo mnohem efektivnější :)