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

Název: PHP imageline() problem [vyřešeno]
Přispěvatel: 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:
Kód: [Vybrat]
<?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]
Název: Re: PHP imageline() problem
Přispěvatel: Tomáš Břinčil 10 Května 2010, 17:14:54
co jinou funkci?
Název: Re: PHP imageline() problem
Přispěvatel: Martin Šácha 10 Května 2010, 19:03:47
Bohužel imagesetpixel() selže na stejném místě taky. :(
Název: Re: PHP imageline() problem
Přispěvatel: Tomáš Břinčil 10 Května 2010, 19:26:09
Tak to je asi nějakým způsobem omezené...
Název: Re: PHP imageline() problem
Přispěvatel: Martin Šácha 10 Května 2010, 19:55:10
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.
Název: Re: PHP imageline() problem
Přispěvatel: Martin Šácha 14 Května 2010, 18:16:34
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.
Název: Re: PHP imageline() problem
Přispěvatel: ETNyx 15 Května 2010, 12:37:18
Kód: [Vybrat]
<?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(0255),mt_rand(0255),mt_rand(0255));
}

$i 0;
for(
$y=0;$y<$vyska;$y++) {
for($x=0;$x<$sirka;$x++) {
imageline($obrazek,$x,$y,$x,$y,$c[mt_rand(04000)]);
$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 :-)
Název: Re: PHP imageline() problem
Přispěvatel: Martin Šácha 16 Května 2010, 20:22:31
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?
Název: Re: PHP imageline() problem
Přispěvatel: ETNyx 17 Května 2010, 00:27:27
Citace
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í  ;).

Citace
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ě.
Název: Re: PHP imageline() problem
Přispěvatel: Martin Šácha 17 Května 2010, 09:26:55
Citace
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ší :)