PHP Forum

PHP Forum (http://www.selfphp.de/forum/index.php)
-   PHP für Fortgeschrittene und Experten (http://www.selfphp.de/forum/forumdisplay.php?f=13)
-   -   seltsames verhalten (http://www.selfphp.de/forum/showthread.php?t=12359)

feuervogel 29.01.2006 23:02:47

seltsames verhalten
 
hallo!

ich weiß nicht genau, ob das hier ein bug im php ist oder ob ich einen fehler im script habe:

PHP-Code:

<?php 
#groesse eines quadrates
$size         50;
#groesse des bildes
$bigsize     400;
#abstand der quadrate zum rand
$margin     2;
#farben
$cols    = array( 'FFFF00' 'ff8000' '80ff00' 'ff0000' '00ff00' 'FF0080' '00ff80' 'ff00ff' '00ffff' '8000ff' '0080ff''0000ff'  );

header("Content-type: image/png");
#bild erstellen
$im     imagecreate$bigsize $bigsize );
#hintergrund weiß färben
$bg     imagecolorallocate($im0xFF0xFF0xFF );
imagefill$im00$bg );

#nun quadrate zeichnen, erst die zeilen dann die spalten
for( $i 0$i $bigsize $size $i++ ) {

    for( 
$j 0$j $bigsize $size $j++ ) {

#zufälligen schlüssel bestimmen
        
$k    rand, ( count$cols ) - ) );
#farbe aussuchen
        
$fill    imagecolorallocate($imhexdecsubstr$cols$k ] , ) ) , hexdecsubstr$cols$k ] , ) ) , hexdecsubstr$cols$k ] , ) ) );
#quadrat malen
        
imagefilledrectangle$im , ( $i $size ) + $margin , ( $j $size ) + $margin , ( ( $i ) * $size ) - $margin , ( ( $j ) * $size ) - $margin $fill );

    }

}
#ausgabe und cache leeren
imagepng($im);
imagedestroy($im);

?>

dies funktioniert im prinzip wunderbar, wähle ich $size sehr klein oder $bigsize sehr groß, so werden die hinteren spalten alle in der gleichen farbe eingefärbt. wieso ist das so?

ich habe das ganze ohne srand gemacht, da ich php5 benutze und es dort nicht nötig ist. exakte version: 5.0.5-2

xabbuh 30.01.2006 09:16:37

AW: seltsames verhalten
 
Mit PHP 4.4.1 kann ich das Problem nicht nachvollziehen. Aber warum benutzt du eigentlich rand() statt array_rand()?

feuervogel 30.01.2006 09:21:04

AW: seltsames verhalten
 
Zitat:

Zitat von xabbuh
Mit PHP 4.4.1 kann ich das Problem nicht nachvollziehen.

hm, okay, dann liegts wohl am php5.

Zitat:

Aber warum benutzt du eigentlich rand() statt array_rand()?
oh? kannte ich gar nicht, werd ich aber mal ausprobieren. danke!

xabbuh 30.01.2006 09:49:44

AW: seltsames verhalten
 
Zitat:

Zitat von feuervogel
hm, okay, dann liegts wohl am php5.

Trotzdem recht merkwürdig. Ich werde das heute abend mal mit meiner 5er Version testen. Mal sehen, ob ich das Problem da dann wenigstens nachvollziehen kann.

feuervogel 30.01.2006 09:50:37

AW: seltsames verhalten
 
also, ich habs jetzt mit array_rand probiert - genau der gleiche fehler:

http://www.julianmoritz.de/dl/bg.png

xabbuh 30.01.2006 09:57:43

AW: seltsames verhalten
 
Ok, jetzt weiß ich, was du mit kleinen Werten für $size meinst (mit 25 hat es bei mir nämlich funktioniert). Bei der Größe, die du in deinem Beispielbild hast, kann ich das Problem nun auch beobachten.

xabbuh 30.01.2006 21:52:03

AW: seltsames verhalten
 
Ich habe gerade noch einmal ein wenig getestet. Anscheinend hat PHP ab einer bestimmten Anzahl an Aufrufen von imagecolorallocate() Probleme. Wenn du den Rückgabewert von imagecolorallocate() zwischenspeicherst und nur bei einer neuen Farbe neu generierst, funktioniert es:
PHP-Code:

<?php
#groesse eines quadrates
$size         50;
#groesse des bildes
$bigsize     400;
#abstand der quadrate zum rand
$margin     2;
#farben
$cols    = array( 'FFFF00' 'ff8000' '80ff00' 'ff0000' '00ff00' 'FF0080' '00ff80' 'ff00ff' '00ffff' '8000ff' '0080ff''0000ff'  );
$generatedColors = array();

header("Content-type: image/png");
#bild erstellen
$im     imagecreate$bigsize $bigsize );
#hintergrund weiß färben
$bg     imagecolorallocate($im0xFF0xFF0xFF );
imagefill$im00$bg );

#nun quadrate zeichnen, erst die zeilen dann die spalten
for( $i 0$i $bigsize $size $i++ ) {

    for( 
$j 0$j $bigsize $size $j++ ) {

#zufälligen schlüssel bestimmen
        
$k    rand, ( count$cols ) - ) );

        if(!
array_key_exists($k$generatedColors))
            
$generatedColors[$k] = imagecolorallocate($imhexdecsubstr$cols$k ] , ) ) , hexdecsubstr$cols$k ] , ) ) , hexdecsubstr$cols$k ] , ) ) );
#quadrat malen
        
imagefilledrectangle$im , ( $i $size ) + $margin , ( $j $size ) + $margin , ( ( $i ) * $size ) - $margin , ( ( $j ) * $size ) - $margin $generatedColors[$k] );

    }

}
#ausgabe und cache leeren
imagepng($im);
imagedestroy($im); 
?>

Beispiel: http://xabbuh.de/image.php

Nachtrag: Anscheinend lassen sich lediglich 255 verschiedene Farben definieren. Jedenfalls liefert imagecolorallocate() ab dem 256. Aufruf -1 zurück.

feuervogel 30.01.2006 23:13:40

AW: seltsames verhalten
 
also was mir vorhin aufgefallen ist, ist dass die verteilung der schlüssel relativ ausgeglichen ist. es liegt also nicht an den randomfunktionen.

wenn man sehr viele kästchen zeichnet, wird das der funktion imagecolorallocate anscheinend "zu schnell". erst wenn man in der äußeren schleife dann zurückspringt, bleibt ein wenig zeit, dass sich die funktion anscheinend "erholt".

zum nachtrag: werde das ganze mal in der bug-database posten, danke für die hilfe, hab schon an mir gezweifelt...

edit: habe jetzt mal versucht mit usleep etwas rumzufrickeln, hat aber nichts genützt, meine überlegungen zu dem "erholen" waren also schwachsinn.

feuervogel 30.01.2006 23:38:54

AW: seltsames verhalten
 
so, das folgende script umgeht das problem.
PHP-Code:

<?php 

$size     
5;
$bigsize     540;
$margin     1;
$colours    = array( 'FFFF00' 'ff8000' '80ff00' 'ff0000' '00ff00' 'FF0080' '00ff80' 'ff00ff' '00ffff' '8000ff' '0080ff''0000ff'  );

//don't change anything under this line

//bild erstellen
header("Content-type: image/png");
$im     imagecreate$bigsize $bigsize );

//weisser hintergrund
$bg     imagecolorallocate($im0xFF0xFF0xFF );
imagefill$im00$bg );

//farben erstellen
$fills    = array();

foreach(
$colours as $v) {

    
$fills[]    = imagecolorallocate($imhexdecsubstr$v ) ) , hexdecsubstr$v ) ) , hexdecsubstr$v ) ) );


}

//mit quadraten fuellen
for( $i 0$i $bigsize $size $i++ ) {

    for( 
$j 0$j $bigsize $size $j++ ) {

        
$k    array_rand$fills );
        
imagefilledrectangle$im , ( $i $size ) + $margin , ( $j $size ) + $margin , ( ( $i ) * $size ) - $margin , ( ( $j ) * $size ) - $margin $fills$k ] );

    }

}

//ausgeben
imagepng($im);
imagedestroy($im);

?>

beweis: http://www.julianmoritz.de/dl/bg2.png

feuervogel 31.01.2006 00:41:02

AW: seltsames verhalten
 
weiteres siehe der eintrag im bugtracker, anscheinend ist das ganze gar kein bug:

http://bugs.php.net/bug.php?id=36218


Alle Zeitangaben in WEZ +2. Es ist jetzt 16:32:16 Uhr.

Powered by vBulletin® Version 3.8.3 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.