Ongelma on yksinkertainen: minulla on alla oleva koodi ja yritän siis pienentää kuvaa lennosta ruudulle.
Nyt sitten jostain syystä tämä koodi tulostaa ruudulle vain tekstipask** kun haluaisin ruudulle kuvan. En halua tallentaa tuota thumbnail kuvaa, haluan vain sen ruudulle.
Mikä siis vikana? Olen erittäin tumpelo tämän grafiikan kanssa. (Jäipä näköjään printit tuohon koodiin kun halusin nähdä mitä tapahtuu missäkin kohtaa...älkää niistä siis välittäkö.)
<?php $kuvan_URL = "00000001.jpg"; function ResizeJpeg( $kuvan_URL, $newWidth, $newHeight) { $srcImage = ImageCreateFromJpeg( "pictures/$kuvan_URL" ); print "$srcImage<br>"; $kuvan_info = getimagesize ( "pictures/$kuvan_URL" ); foreach ( $kuvan_info as $key=>$val ) { print "$val<br>"; } $srcHeight = $kuvan_info[0]; $srcWidth = $kuvan_info[1]; print "$srcWidth<br>"; print "$srcHeight<br>"; if ( $srcWidth > $srcHeight ) { $destWidth = 100; $destHeight = floor(100 * $srcHeight / $srcWidth); print "leveys on suurempi<br>Uusi leveys on $destWidth ja korkeus on $destHeight"; } else { $destHeight = 100; $destWidth = floor(100 * $srcWidth / $srcHeight); print "korkeus on suurempi<br>Uusi leveys on $destWidth ja korkeus on $destHeight"; } $destImage = imagecreatetruecolor( $destWidth, $destHeight ); print "$destImage<br>"; print "$kuvan_URL<br>"; print "small_pictures/$kuvan_URL<br>"; $uusikuva = imagecopyresampled( $destImage, $destImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight ); imagejpeg( $destImage, "small_pictures/$kuvan_URL" ); //free the memory used for the images ImageDestroy( $srcImage ); ImageDestroy( $destImage ); } ?>
Lisäämällä koodin alkuun tämän
header("Content-type: image/png");
niin selain tunnistaa, että kyseessä on kuva. Tuota koodiasi en tarkkailut paljoa, mutta uskon, että tuo auttaa ongelmaasi.
Ja lisätäänpä vielä, että tuossa et mitään tee rivinvaihdoilla(
), koska sivu on kuva.
Oikea aloitus on tässä tapauksessa:
header("Content-type: image/jpeg");
Ja jos siis haluat kuvan suoraan näkyviin sivulle, ota pois imagejpeg-funktion toinen parametri, joka määrittää kuvatiedoston nimen.
No niin. Muokkasin hieman typeriä virheitä ja nyt minulla on seuraava koodi:
<?php function ResizeJpeg( $kuvan_URL, $newWidth, $newHeight) { $kuvan_info = getimagesize ( "$kuvan_URL" ); if ( $kuvan_info[2] == 2) { header("Content-type: image/jpeg"); $srcImage = imagecreatefromjpeg( "$kuvan_URL" ); } //else die(); $srcHeight = $kuvan_info[0]; $srcWidth = $kuvan_info[1]; if ( $srcWidth > $srcHeight ) { $destWidth = 100; $destHeight = floor(100 * $srcHeight / $srcWidth); } else { $destHeight = 100; $destWidth = floor(100 * $srcWidth / $srcHeight); } $destImage = imagecreatetruecolor( $destWidth, $destHeight ); imagecopyresampled( $destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight ); imagejpeg( $destImage ); // Vapauta muisti ImageDestroy( $srcImage ); ImageDestroy( $destImage ); } ?>
Ja virhe on seuraava:
Warning: Cannot modify header information - headers already sent by (output started...
Mikä menee vikaa? Sanottakoon vielä, että kutsun tuota funktiota seuraavasti:
$kuvan_URL = "pictures/00000001.jpg";
ResizeJpeg( "$kuvan_URL", 100, 100);
Olikohan tuossa nyt kaikki?
Jatketaan samaan viestiin:
Siis tuo header virhehän tulee siitä kun tuo kuva halutaan tulostaa keskelle sivua. Eli sivuni koostuu monesta osasta jossa ensimmäisessä otetaan <HEAD></HEAD> ja kaikki siltä väliltä. Sitten tuo kuva tulee siellä jossakin. Usea sivu yhdistetään include funktiolla.
Nähtävästi siis vika on tuossa(?). Mutta pystynkö kiertämään tuota ongelmaa vai mitä teen?
Ennen headeria ei saa olla mitään.. Ei edes <html>-tagia. Tätä ongelmaa on kyllä kysytty niin paljon, eikä vieläkään mene kaaliin!
Vika on juuri siinä: ennen header-funktiota ei saa sivulle tulostaa mitään. Ongelma ratkeaa siten, että teet tuosta kuvan muodostamisesta erillisen PHP-tiedoston, jonka sitten näytät sivulla vaikkapa tähän tapaan:
<img src="kuva.php?url=00000001.jpg">
Jos samanniminen kuva pysyy aina muuttumattomana, voisi tosin olla järkevää luoda kuvan pienennetty versio vain kerran (silloin, kun uusi kuva lisätään sivuille) ja tallentaa se erilliseen tiedostoon. Tuollaisen skriptin suorittaminen aina, kun kuva näytetään, voi olla nimittäin palvelimelle raskasta.
elikkäs ne vanhat ob_start() ja ob_end_flush() funkkarit niin, että ob_start() on heti alotustagin jälkeisellä rivillä, ja ob_end_flush() taas riviä ennen lopetustagia, hyvä muistisääntö.
<?php ob_start(); print"jee"; print"jee"; print"jee"; ob_end_flush(); ?>
Muoks:
Jaaha, Antti vinkkasi myös. Noh, tuossa yleispätevä ohje headereiden tulostamiseen.
Nyntti kirjoitti:
elikkäs ne vanhat ob_start() ja ob_end_flush() funkkarit niin, että ob_start() on heti alotustagin jälkeisellä rivillä, ja ob_end_flush() taas riviä ennen lopetustagia, hyvä muistisääntö.
Jos skripti muodostaa kuvan, näiden funktioiden käyttäminen ei auta ongelmaan. Kuvan alkuun ei saa nimittäin tulostaa ylimääräistä tekstiä edes header-funktion jälkeen.
Kun nyt tarpeeksi päätäni raaputin, niin sain ongelmat ratkaisua. Kiitos siitä siis niille kenelle kiitos kuuluu.
Asiaan liittyen kuitenkin lisäkysymys. Kuinka saan tämän funktion sellaiseksi, että suuremman kantin maksimiluku on vaikka 100?
Koodi on tässä (ja se toimii):
<?php function resizejpeg( $kuvan_URL ) { $kuvan_info = getimagesize ( "$kuvan_URL" ); if ( $kuvan_info[2] == 2) { header("Content-type: image/jpeg"); $srcImage = imagecreatefromjpeg( "$kuvan_URL" ); } //else die(); $srcWidth = $kuvan_info[0]; $srcHeight = $kuvan_info[1]; if ( $srcHeight < $srcWidth ) { $suhde = ( $srcWidth / $srcHeight ); $destHeight = 100; $destWidth = floor( 100 * $suhde ); } else { $suhde = ( $srcHeight / $srcWidth ); $destWidth = 100; $destHeight = floor( 100 * $suhde ); } $destImage = imagecreatetruecolor( $destWidth, $destHeight ); imagecopyresized( $destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight ); imagejpeg( $destImage ); // Vapauta muisti ImageDestroy( $srcImage ); ImageDestroy( $destImage ); } ?>
Aihe on jo aika vanha, joten et voi enää vastata siihen.