Kirjautuminen

Haku

Tehtävät

Koodivinkit: PHP: Kuvagalleria

Kirjoittaja: sooda; viimeksi muokattu 19.04.2013.

Päivitetty 28.4.2007.
Pikkumuokkaus 3.6.08: hak.php bugas, navikuvat linkkas ei-htaccess-moodissa vähän väärin.

Helppokäyttöinen (?) kuvagalleria. Monta kuvahakemistoa, pikkukuvat generoidaan automaagisesti kuhan oikeudet ovat kunnossa, sivustukin toimii (tein lähinnä siks, että yhden ison sivun kuvien latailu saattais olla haitaksi kaistalleni kun tuo kotiserverilläni sijaitsee -- tietysti jotkut sivutuksesta tykkäävätkin, hyvä se mahdollisuus on ollaki, ite en yleensä kyllä oikeastaan tykkää), myslikommentointikin on. Ihana apachen mod_rewrite-kikkailu helpottaa urleja. Itselläni käytössä osoitteessa http://sooda.dy.fi/foo/kuvagalleria/ -- katso esimerkkejä toiminnasta. Kaverilla kans vähän muunneltuna: http://kapsi.fi/~sciatic/galleria/

Osaa tehdä thumbit jpg-, png- ja gif-tyyppisistä kuvista.

Käyttöönotto:
1) Tökkää koodit johonkin tiettyyn samaan hakemistoon
2) SÄÄDÄ se asetukset.php!! Ja jos rewrite on päällä, niin käytä .htaccessia. Jos ei niin poista .htaccess tai kommentoi nuo säännöt pois tai sano rewriteengine off tms.
3) muokkaa ehkä jotain jos huvittaa

Kuvahakemiston käyttöönotto:
1) tee sopivan niminen hakemisto sinne, missä koodit sijaitsevat. Nimessä ei ole kiva olla ainakaan ääkkösiä tms. erkkarimerkkejä, jotkut selaimet varmaan evottaa.
2) laita tähän hakemistoon hakemistot orig, medi ja thmb.
3) Orig-hakemistoon laitat originaalit kuvat.
4) Php-skripteillä on oltava oikeus kirjoittaa hakemistoihin medi ja thmb, koska ne kirjoittelevat sinne automaagisesti kokomuutetut kuvat. Tietysti kivaa on kans tehdä joku oneliner-päshskripti joka muuttaa koot imagemagickilla etukäteen vaikka, ettei palvaimelle tulis kauheasti rasitusta. Tyyliin cd orig; for i in *; do convert $i -resize SOPIVAKOKO ../thmb/$i; done ja sama medille. Windowsisteille sitte vaikka irfanviewin batch mode tms.
5) Myös itse pääkuvahakemistoon (siis sinne, missä orig-hakemisto ym. sijaitsevat) pitää saada kirjoittaa; sinne tehdään index.jpg, jossa on neljä hakemiston kuvaa.
6) Ei orig-hakemiston kirjotusoikeuksista mitään haittaakaan ole. Riittää siis kun muoksii rekursiivisesti kuvahakemiston oikeudet, elikkä foo-kuvahakemiston luonti toimis tyyliin mkdir foo foo/orig foo/medi foo/thmb; chmod -R g+w foo; chown -R apache foo jos komentoriville pääsee -- tosta voi tehdä pienen skriptinkin ettei tarvi toistaa. Muokkaa apache ryhmäksi joka palvelimellasi ajelee httpd:tä. (hyvissä ftp-clienteissäkin on varmaan rekursiivinen chmod, en niistä tosin tiä) Php on siitä ikävä että ainaki safemodessa sillä ei kannata käyttää mkdiriä mihinkään, mutta ei siitä sen enempää, mokomasta päänvaivasta voisi angstata koko päivän.

Kuvahakemiston päivittäminen:
1) laita päivitettäv(i)ä kuv(i)a orig-hakemistoon. Koodi hoitaa loput.

Kuvahakemistoon voi tehdä info.php-tiedoston joka sisällytetään hakemiston kuvalistauksen alkuun. Myös kuvien nimiset, .php-päätteiset tiedostot siellä toimivat yksittäisinä kuvauksina kuville (tyyliin munkuva.jpg.php)

Kuvien koot tarkistellaan aina, eli jos asetuksista vaihtaa vaikka thumbin kokoa niin ne generoidaan automaagisesti oikean kokoisiksi jos väärän kokoisia on.

HUOMIO niille oudokkeille joilla palvelinsofta on windows: muoksi asetukset.php:ssä olevasta pikkukuva-funktiosta symlink kopioinniksi, windows kun symlinkkejä ei tue.

Erillinen thumpi.php eikä kuvien generointia listasivulle siksi, että hitaahkolla koneella useamman thumbin pulauttaminen kestää hetkisen, varsinkin jos originaalit ovat suuria. Vierailija sitten mahdollisesti kyllästyy odottamiseen ja päivittää sivun ihan turhaan. Näin taas listaussivu latautuu heti, ja joka kuva sitten omalla ajallaan kun on saanut thumbin generoitua (näin siis ekalla kerralla, kun thumbia ei vielä ole). Muutenkin tota thumpigeneroijaa voi soveltaa helpohkosti muuallekin.

HUOMIO! Valtavia kuvia ei vaan pysty käsittelemään jos php:llä on pienehkö muistirajoitus (memory_limit php.inissä)

Jos ei toimi tai ei pikkukuvat näy niin korjaa ne tiedosto-oikeudet, niissä se vika todennäköisesti on. Tarkista kahdesti että php saa kirjoittaa sinne minne tarvitsee, debuggaa (katso kuvien sisällöt mahdollisista virheilmoituksista yms., kaiva vaikka sijainnit html-lähdekoodista jos sivulla ei kuvat näy), tarkista että symlinkkejä saa käyttää ja tule sitten vasta kyselemään lisää jos ei vieläkään toimi.

Bugeista (joita varmaan on, en ihan kaikkia ominaisuuksia ole täysin testannut kai) ja/tai ominaisuustoiveista/valituksista tms. saa kernaasti ilmoitella.

Jos et jaksa copypasteilla noita koodeja niin löytyvät nuo koodit paketeissakin: http://sooda.dy.fi/foo/kuvagalleria/galleria.tar.gz tai http://sooda.dy.fi/foo/kuvagalleria/galleria.zip

asetukset.php

<?php
// otsikkoriville ja h1:ksi
$title = "galleria";
// montako kuvaa sivulle
$sivulleyht = 16;
/* pikkukuvan koko. vastaava tyyleihin sit myös.
 * jos kuva on eri muotoinen (eri kuvasuhteet),
 * pikkukuvasta tehdään mahdollisimman iso kuvasuhde säilyttäen.
 */
$t_wid = 160;
$t_hei = 120;
// hakemistoesikattelukuvan taustaväri, 0..255
$hakesitausta = array(0, 0, 0);
// keskikokoisen "esikatselukuvan" koko (kuva.php:ssä).
$m_wid = 640;
$m_hei = 480;
// käytetäänkö apachen ihkuja rewritehommeleita lyhentämään urlit tyyliin /kuva.php?d=hak&i=img.jpg -> /hak/img.jpg
$rewrite = true;
// gallerian osoite serverillä; rewritekikka vaihtaa selaimelle näkyvän hakemiston
$base = "/foo/kuvagalleria";
// navigaatiokuvat vasemmalla ja oikealla edelliseen ja seuraavaan hakemistoon pikkukuvien listauksessa
$haknavi = false;
// navikuvat kuvan katselussa
$listnavi = true;
// kuvien kommentointi päälle esikattelusivulla?
$kommentointi = true;
// jos käytetään kommentointia, tökkää tähän urli skriptiin jossa on yhdistäminen ja kannan valinta (tai haksaa ne suoraan kuva.php:hen)
//create table kuvagalleria (id int unsigned not null auto_increment, hak varchar(255) not null, kuva varchar(255) not null, aika datetime not null, nick varchar(10) not null, msg varchar(255) not null, ip varchar(15) not null, primary key (id))
$mysqlinit = "/joku_salainen_polku_mielellaan/mysli.php";
// kommenttien poistoon adminin tunnistus, muokkaa mieleiseksi
$ADMIN = $_SERVER["REMOTE_ADDR"] == "192.168.0.2";
// jpg-pakkauksen taso, 0 = surkea laatu, pieni tiedostokoko; 100 = hyvä laatu, isompi tiedostokoko.
$laatu_thmb = 90;
$laatu_medi = 70;
// postia jolleki uuden kommentin tullessa. epäkommentoi niin lähetetään
// $mail = "foo@bar.tld";

// ja pari yleiskäyttöstä funkkaria tänne.

// fileorig ja -thmb kuvien nimet, t_wid ja t_hei thumpin koko. kuvasuhde säilyy. palautusarvo kertoo, onnistuiko, laatu jpeg-laatu (100 paras)
function pikkukuva($fileorig, $filethmb, $t_wid, $t_hei, $laatu) {
	if (file_exists($filethmb)) {
		list($wid, $hei) = getimagesize($filethmb);
		// pitää olla niin iso että mahtuu juuri ja juuri
		if ($wid > $hei) $pahakoko = $wid != $t_wid;
		else $pahakoko = $hei != $t_hei;
	}
	// tehään thumbikuva vain jos sitä ei vielä löydy tai on väärän kokoinen
	if (!file_exists($filethmb) || $pahakoko) {
		$imgorig = kuvasta($fileorig);
		if ($imgorig == null) return false;

		list($wid, $hei) = getimagesize($fileorig);
		if ($wid <= $t_wid && $hei <= $t_hei) {
			// pöh höh, kokonaan pienempi kuin mitä tarttis. linkataan
			// windows-käyttäjät hox hox vaihtakoot filecopyks
			if (!file_exists($filethmb)) symlink(getcwd() . "/" . $fileorig, $filethmb);
			return true;
		} else if ($wid / $hei > $t_wid / $t_hei) $t_hei = $t_wid / $wid * $hei; // muoto pysyy
		else $t_wid = $t_hei / $hei * $wid;
		// ja sitten kopsitaan pikkukuva.
		$imgthmb = imagecreatetruecolor($t_wid, $t_hei);
		imagecopyresampled($imgthmb, $imgorig, 0, 0, 0, 0, $t_wid, $t_hei, $wid, $hei);
		imagedestroy($imgorig);
		imagejpeg($imgthmb, $filethmb, $laatu);
		imagedestroy($imgthmb);
	}
	return true;
}
// Jos onnistuu, niin ladataan kuvatiedosto.
function kuvasta($nimi) {
	$info = @getimagesize($nimi);
	$tyypi = $info[2];
	$funks = array(IMAGETYPE_JPEG => "imagecreatefromjpeg", IMAGETYPE_PNG => "imagecreatefrompng", IMAGETYPE_GIF => "imagecreatefromgif");
	if (!isset($funks[$tyypi])) return null;
	return $funks[$tyypi]($nimi);
}

// tyyliin palle.jpg -> palle
function paatepois($f) {
	$piste = strpos($f, ".");
	if ($piste === false) return $f;
	return substr($f, 0, $piste);
}
?>

index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">

<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=iso-8859-1" />
<title><?php include "asetukset.php"; echo $title; ?></title>
<style type="text/css">@import "<?php echo $base; ?>/staili.css";</style>
</head>

<body>
<h1><?php echo $title; ?></h1>
<?php
$hakit = glob("*", GLOB_ONLYDIR);
echo "<p>Valitse hakemisto:</p>\n";
echo "<ul id=\"kuvalodju\">\n";
if ($rewrite) {
	foreach ($hakit as $hak) echo "\t<li><a href=\"$hak/\"><img src=\"thumpi.php?d=$hak\" alt=\"\" /> $hak</a></li>\n";
} else {
	foreach ($hakit as $hak) echo "\t<li><a href=\"hak.php?d=$hak\"><img src=\"thumpi.php?d=$hak\" alt=\"\" /> $hak</a></li>\n";
}
?>
<p style="clear: both">Sorsa on auki. <a href="http://www.ohjelmointiputka.net/koodivinkit/23929-php-kuvagalleria">selite</a> | <a href="galleria.tar.gz">tar.gz</a> | <a href="galleria.zip">zip</a></p>
</body>
</html>

hak.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">

<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=iso-8859-1" />
<title><?php include "asetukset.php"; echo $title; ?></title>
<style type="text/css">@import "<?php echo $base; ?>/staili.css";</style>
</head>

<body>
<h1><?php echo '<a href="' . ($rewrite ? "../" : "./") . "\">$title</a>"; ?></h1>
<?php
$hak = $_GET["d"];
// hakemisto olemassa ja oikeassa paikassa
if (!is_dir($hak) || dirname($hak) != "." || realpath($hak) == realpath(".") || $hak == "..") die("<p>Hakemistoa ei löydy!</p></body></html>");

echo "<h2>$hak</h2>\n";

if ($haknavi) { // navikuvat
	$hakit = glob("*", GLOB_ONLYDIR);
	$id = array_search($hak, $hakit);
	if ($id != 0) { // ensimmäisellä ei ole edellistä
		$h = $hakit[$id - 1];
		echo '<div class="navikuva" id="taaksenavi"><a href="' . ($rewrite ? "$base/$h" . '"><img src="' . "$base/thumpi.php?d=$h" : "?d=$h" . '"><img src="' . "$base/thumpi.php?d=$h") . '" alt="" /> ' . $h . '</a></div>';
	}
	if ($id != count($hakit) - 1) { // eikä viimeisen jälkeen tule mitään
		$h = $hakit[$id + 1];
		echo '<div class="navikuva" id="eteennavi"><a href="' . ($rewrite ? "$base/$h" . '"><img src="' . "$base/thumpi.php?d=$h" : "?d=$h" . '"><img src="' . "$base/thumpi.php?d=$h") . '" alt="" /> ' . $h . '</a></div>';

	}
}

// chdir, et saadaan pelkät kuvien nimet ilman hakemistonimeä.
chdir("$hak/orig");
$kuvat = glob("*");
chdir("../..");

$määrä = count($kuvat);
$sivujenmäärä = ceil($määrä / $sivulleyht);
if (isset($_GET["p"])) {
	$sivu = (int)$_GET["p"];
	if ($sivu < 0 || $sivu >= $sivujenmäärä) die("<p>Sivua ei ole!</p></body></html>");
} else $sivu = 0;

/* sivunvalitsemisroina. linkeiksi vain ne, jotka vaihtavat sivua,
 * esim. jos sivu on eka, ei linkata taaksepäin eikä ekalle.
 * tökätään muuttujaan, ku tulostetaan kaks kertaa - kuvien ylle ja alle.
 * alkaa nollasta. konffi mikäli ei tyydytä */
if ($sivujenmäärä > 1) {
	$rullaus = "<p> sivut: ";
	if ($rewrite) {
		$rullaus .= $sivu == 0 ? "<- " : '<a href="' . ($sivu - 1) . '"><-</a> ';
		for ($i = 0; $i < $sivujenmäärä; $i++) $rullaus .= $i == $sivu ? "$i " : "<a href=\"$i\">$i</a> ";
		$rullaus .= $sivu == $sivujenmäärä - 1 ? "->" : '<a href="' . ($sivu + 1) . '">-></a>';
	} else {
		$rullaus .= $sivu == 0 ? "<- " : "<a href=\"?d=$hak&p=" . ($sivu - 1) . '"><-</a> ';
		for ($i = 0; $i < $sivujenmäärä; $i++) $rullaus .= $i == $sivu ? "$i " : "<a href=\"?d=$hak&p=$i\">$i</a> ";
		$rullaus .= $sivu == $sivujenmäärä - 1 ? "->" : "<a href=\"?d=$hak&p=" . ($sivu + 1) . '">-></a>';
	}
	$rullaus .= "</p>";
} else $rullaus = "";
// jos on selite hakemistosta, niin otetaan se
if (is_file("$hak/info.php")) include "$hak/info.php";

echo "<div id=\"kuvalodju\">$rullaus\n<ul>\n";
$loppu = $sivulleyht * ($sivu + 1); // viimeinen näytettävä kuva sivulla
if ($määrä < $loppu) $loppu = $määrä;

for ($i = $sivulleyht * $sivu; $i < $loppu; $i++) {
	$kuva = $kuvat[$i];
	echo $rewrite ? "\t<li><a href=\"$base/$hak/$kuva\"><img src=\"$base/$hak/$kuva/thmb\" alt=\"\" /> " . paatepois($kuva) . "</a></li>\n"
	:  "\t<li><a href=\"kuva.php?d=$hak&i=$kuva\"><img src=\"thumpi.php?d=$hak&i=$kuva\" alt=\"\" /> " . paatepois($kuva) . "</a></li>\n";
}
echo "</ul>\n$rullaus\n</div>";
?>
</body>

</html>

kuva.php

<?php include "asetukset.php"; ob_start(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">

<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=iso-8859-1" />
<title><?php echo $title; ?></title>
<style type="text/css">@import "<?php echo $base; ?>/staili.css";</style>
</head>

<body>
<h1><?php echo '<a href="' . ($rewrite ? "../" : "./") . "\">$title</a>"; ?></h1>
<?php
if (!isset($_GET["d"]) || !isset($_GET["i"])) die("<p>Kuvaa ei annettu!</p></body></html>");
$hak = $_GET["d"];
if (!is_dir($hak) || dirname($hak) != "." || realpath($hak) == realpath(".") || $hak == "..") die("<p>Hakemistoa ei löydy!</p></body></html>");
$kuva = $_GET["i"];
if (!is_file("$hak/orig/$kuva") || (dirname("$hak/orig/$kuva") != "$hak/orig")) die("<p>Kuvaa $kuva ei löydy!</p></body></html>");

chdir("$hak/orig/"); $filet = glob("*"); chdir("../..");

// hakemiston nimen klikkaaminen vie sivulle, jossa tämä kuva on
$id = array_search($kuva, $filet);
$sivu = floor($id / $sivulleyht);
if ($sivu == 0) echo $rewrite ? "<h2><a href=\"$base/$hak/\">$hak</a></h2>\n" : "<h2><a href=\"./hak.php?d=$hak\">$hak</a></h2>\n";
else echo $rewrite ? "<h2><a href=\"$base/$hak/$sivu\">$hak</a></h2>\n" : "<h2><a href=\"./hak.php?d=$hak&p=$sivu\">$hak</a></h2>\n";

if ($listnavi) { // edellinen ja seuraava kuva
	if ($id != 0) {
		$k = $filet[$id - 1];
		echo '<div class="navikuva" id="taaksenavi"><a href="' . ($rewrite ? "$base/$hak/$k" . '"><img src="' . "$base/$hak/$k/thmb" : "kuva.php?d=$hak&i=$k" . '"><img src="' . "$hak/thmb/$k") . '" alt="" /> ' . paatepois($k) . '</a></div>';
	}
	if ($id != count($filet) - 1) {
		$k = $filet[$id + 1];
		echo '<div class="navikuva" id="eteennavi"><a href="' . ($rewrite ? "$base/$hak/$k" . '"><img src="' . "$base/$hak/$k/thmb" : "kuva.php?d=$hak&i=$k" . '"><img src="' . "$hak/thmb/$k") . '" alt="" /> ' . paatepois($k) . '</a></div>';
	}
}
echo "<h3>$kuva</h3>\n";

// kuvalle saa selitettä. tiedostonimi tyyliin kuva.jpg.php
if (is_file("$hak/$kuva.php")) include "$hak/$kuva.php";

// jos esikattelukuvan tekeminen ei onnistu, näytetään originaali kuva.
$tyyppi = pikkukuva("$hak/orig/$kuva", "$hak/medi/$kuva", $m_wid, $m_hei, $laatu_medi) ? "medi" : "orig";
echo $rewrite ? "<p><a href=\"$base/$hak/$kuva/orig\" id=\"medikuva\"><img src=\"$base/$hak/$kuva/$tyyppi\" alt=\"[$kuva]\" /></a></p>\n"
	: "<p><a href=\"$hak/orig/$kuva\" id=\"medikuva\"><img src=\"$hak/medi/$kuva\" alt=\"[$kuva]\" /></a></p>\n";
// kivaa tietoa kuvasta jos kameralla kuvattu
$exif = @exif_read_data("$hak/orig/$kuva");
if ($exif) {
	echo "<p>" . date("j.n.Y H:i:s", $exif["FileDateTime"]);
	if (strpos($exif["SectionsFound"], "EXIF") !== false) {
		$make = trim($exif["Make"]);
		$model = trim($exif["Model"]);
		//tuplat pois
		if (strtolower(substr($model, 0, strlen($make))) != strtolower($make)) echo ", $make";
		echo ", " . trim($exif["Model"]) . ", " . muotoileluku($exif["ExposureTime"]) . "s, f/" . muotoileluku($exif["FNumber"]) . "@" . muotoileluku($exif["FocalLength"]) . "mm, iso" . $exif["ISOSpeedRatings"] . ", " . exifflash($exif["Flash"]) . ".";
	}
	echo "</p>\n";
}
function muotoileluku($data) { // sievempään muotoon kameran antamat tyhmät, esim "10/1000" -> "1/100"
	if (!preg_match('/(\d+)\/(\d+)/e', $data, $info)) return $data;
	$val = $info[1] / $info[2];
	if ($val > 1 || 1 / $val != (int)(1 / $val)) return $val;
	else return "1/" . (1 / $val);
}
function exifflash($v) {
	// spekseistä lueskelin
	if (($v & 1) == 0) return "ei salamaa";
	if ((($v >> 3) & 3) == 3) return "salama (auto)";
	return "salama";
}

if ($kommentointi) {
	@include $mysqlinit;
	if ($ADMIN && isset($_POST["del"])) {
		// hus pois valitut, id-numerot taulukon arvoissa
		$del = implode("' OR id = '", $_POST["del"]);
		mysql_query("DELETE FROM kuvagalleria WHERE id = '$del'");
		header("Location: " . ($rewrite ? $kuva : "kuva.php?d=$hak&i=$kuva"));
	}
	if (isset($_POST["nick"]) && isset($_POST["msg"])) {
		$nik = mysql_real_escape_string(get_magic_quotes_gpc() ? stripslashes($_POST["nick"]) : $_POST["nick"]);
		$msg = mysql_real_escape_string(get_magic_quotes_gpc() ? stripslashes($_POST["msg"]) : $_POST["msg"]);
		if (trim($nik) != "" && trim($msg) != "") {
			// floodiesto
			$q = mysql_query("SELECT COUNT(id) FROM kuvagalleria WHERE hak = '$hak' AND kuva = '$kuva' AND ip = '$_SERVER[REMOTE_ADDR]' AND DATE_SUB(NOW(), INTERVAL 5 MINUTE) <= aika");
			if (mysql_result($q, 0) < 2) {
				mysql_query("INSERT INTO kuvagalleria (hak, kuva, nick, msg, aika, ip) VALUES ('$hak', '$kuva', '$nik', '$msg', NOW(), '$_SERVER[REMOTE_ADDR]')");
				$url = "http://$_SERVER[HTTP_HOST]$base/" . ($rewrite ? "$hak/$kuva" : "kuva.php?d=$hak&i=$kuva");
				if (isset($mail)) @mail($mail, "galsukomsu $hak/$kuva", "$url\n<$nik> $msg");
				header("Location: " . ($rewrite ? $kuva : "kuva.php?d=$hak&i=$kuva"));
			} else echo "<p>VIRHE: Käyttäydy kunnolla, saman ip-osoitteen takaa voi lähettää vain kaksi viestiä samaan kuvaan viiden minuutin sisällä.</p>\n";
		}
	}

	// listaillaan kommentit ja poistoruksit jos admin kyseessä
	$q = @mysql_query("SELECT id, DATE_FORMAT(aika, '%d.%m.%Y %H:%i:%s') AS taim, nick, msg FROM kuvagalleria WHERE hak = '$hak' AND kuva = '$kuva' ORDER BY aika");
	if (!$q) echo "<p>Kommentointi on särki.</p>";
	else {
		if (mysql_num_rows($q) == 0) echo "<p>Ei kommentteja</p>\n";
		else {
			if ($ADMIN) echo '<form method="post" action="' . ($rewrite ? $kuva : "kuva.php?d=$hak&i=$kuva") . '">';
			echo "<table id=\"komsut\">\n";
			while ($r = mysql_fetch_assoc($q)) {
				echo "<tr>" . ($ADMIN ? '<td><input type="checkbox" name="del[]" value="' . $r["id"] . '" /></td>' : '') . "<td><" . htmlentities($r["nick"]) . "></td><td>" . htmlentities($r["msg"]) . "</tr>\n";
			}
			echo "</table>\n";
			if ($ADMIN) echo '<p><input type="submit" value="poista valitut" /></p></form>';
		}
		echo '<form method="post" action="' . ($rewrite ? "$base/$hak/$kuva" : "?d=$hak&i=$kuva") . '"><p><<input type="text" name="nick" size="10" maxlength="10" />> <input type="text" name="msg" size="40" maxlength="255" /><input type="submit" value="sano" /></p></form>';
	}
}
?>
</body>

</html>
<?php ob_end_flush(); ?>

thumpi.php

<?php include "asetukset.php";
// hakemisto ja kuva urlista
if (isset($_GET["d"])) $hak = $_GET["d"]; else die();
// olemassa ja oikeassa paikassa
if (!is_dir($hak) || dirname($hak) != "." || realpath($hak) == realpath(".") || $hak == "..") die();
if (isset($_GET["i"])) { // tehdään pikkukuva
	$kuva = $_GET["i"];
	$orig = "$hak/orig/$kuva";
	if (!is_file($orig)) die();
	$thmb = "$hak/thmb/$kuva";
	pikkukuva($orig, $thmb, $t_wid, $t_hei, $laatu_thmb);
	header("Content-type: image/jpeg");
	readfile($thmb);
} else { // tehdään esikatselu hakemistosta
	// ei tehdä kuvaa turhaan jos se on jo olemassa.
	if (!is_file("$hak/index.jpg")) {
		// kuvan koko neljäsosa pikkukuvasta (neljä kuvaa pikkukuvaan)
		$tw = $t_wid / 2 - 1;
		$th = $t_hei / 2 - 1;
		$i = imagecreatetruecolor($t_wid, $t_hei);
		$clr = imagecolorallocate($i, $hakesitausta[0], $hakesitausta[1], $hakesitausta[2]);
		imagefilledrectangle($i, 0, 0, $t_wid - 1, $t_hei - 1, $clr);
		$filet = glob("$hak/orig/*");
		$c = count($filet);
		if ($c < 4) { // alle neljä kuvaa. otetaan vain ne
			$idt = range(0, $c - 1);
		} else { // ei oteta tylsästi neljää ekaa, vaan tasaisesti alusta loppuun
			$idt = array(0, ($c - 1) / 3, ($c - 1) / 3 * 2, $c - 1);
			$c = 4;
		}
		// ja väsätään pikkukuvaan ne.
		for ($k = 0; $k < $c; $k++) {
			$id = (int)$idt[$k];
			$j = kuvasta($filet[$id]);
			if (!$j) continue; // epätuettu kuvamuoto
			list($wid, $hei) = getimagesize($filet[$id]);

			// muoto kuntoon
			if ($wid <= $tw && $hei <= $th) {
				$kw = $wid;
				$kh = $hei;
			} else if ($wid / $hei > $t_wid / $t_hei) {
				$kw = $tw;
				$kh = $tw / $wid * $hei;
			} else {
				$kw = $th / $hei * $wid;
				$kh = $th;
			}
			// oolrait, sopiva kuva sopivaan kohtaan.
			imagecopyresampled($i, $j, $k & 1 ? $tw + 1 : 0, $k & 2 ? $th + 1 : 0, 0, 0, round($kw), round($kh), $wid, $hei);
			imagedestroy($j);
		}
		// kuva tulee mukavasti tähän hakemistoon, ettei muut kuvaskriptit sitte löydä sitä.
		imagejpeg($i, "$hak/index.jpg", $laatu_thmb);
		imagedestroy($i);
	}
	header("Content-type: image/jpeg");
	readfile("$hak/index.jpg");
}
?>

staili.css

html {
	background: #000;
}
body {
	color: #fff;
	background: #000;
	padding: 4px;
	margin: 0;
	text-align: center;
	font-family: verdana, sans-serif;
	font-size: 13px;
}
a {
	color: #fff;
}
p a:hover {
	text-decoration: none;
}
#kuvalodju {
	margin: 0 auto;
	width: 725px;
}
#kuvalodju ul {
	margin: 0;
 	padding: 0;
 	overflow: hidden;
}
#kuvalodju li {
	float: left;
 	list-style-type: none;
}
#kuvalodju li a, .navikuva a {
	width: 160px;
	height: 142px;
	display: block;
	border: 1px solid #000;
	padding: 5px;
	text-decoration: none;
	overflow: hidden;
}
#kuvalodju li a {
	margin: 2px;
}
#taaksenavi {
	float: left;
}
#eteennavi {
	float: right;
}
#kuvalodju li a:hover, .navikuva a:hover {
	border: 1px solid #fff;
	text-decoration: underline;
}
img {
	border: none;
	margin: 0 auto;
}
#kuvalodju img, .navikuva a img {
	display: block;
}
#komsut {
	margin: 0 auto;
}
a#medikuva img {
	border: 2px solid #000;
}
a#medikuva:hover img {
	border: 2px solid #fff;
}

.htaccess

RewriteEngine On
# hak/
RewriteRule ^([^\/]+)/$ hak.php?d=$1
# hak/sivunro
RewriteRule ^([^\/]+)/([0-9]+)$ hak.php?d=$1&p=$2
# #hak/kuva
RewriteRule ^([^\/]+)/([^\/]+)\/?(?<!(orig|thmb|medi))$ kuva.php?d=$1&i=$2
# hak/kuva/orig tai hak/kuva/medi
RewriteRule ^([^\/]+)/([^\/]+)/(orig|medi)$ $1/$3/$2
# hak/kuva/thmb
RewriteRule ^([^\/]+)/([^\/]+)/thmb$ thumpi.php?d=$1&i=$2
# usein tuo on pois päältä oletuksena, pikkukuvissa on symlinkkejä.
Options FollowSymLinks

Kommentit

str4nd [01.06.2006 17:40:17]

Lainaa #

Mä oon niin ilkeä ja kerron .htaccessin:

Options -Indexes

Heikki [06.06.2006 21:15:16]

Lainaa #

Thumbbaaja näyttäisi osaavan vain .jpeg-kuvia. Jos joku ottaa tämän käyttöön niin kannattaa laittaa tuo tiedostopäätteen mukaan käyttämään joko jpeg, png tai gif -funktioita.

sooda [06.06.2006 22:37:06]

Lainaa #

Hyvä huomio, Heikki. Päivitin tommoisen tunnistuksen tuohon.

Antti Laaksonen [07.06.2006 01:09:13]

Lainaa #

Toimiva systeemi. Tätä voi suositella, kun joku etsii kuvagalleriaa.

alussa [14.06.2006 13:26:08]

Lainaa #

Kun en tajua miten tuossa on tehty tuo ison kuvan skaalautuminen selaimen ikkunaan sopivaksi. Olen sellaista yrittänyt mutta ei oikein onnistu, voisiko joku selventää kiitos.
Olen vielä aika alkuasteilla näissä hommissa.

sooda [14.06.2006 23:14:04]

Lainaa #

Häh, ei tuo selainikkunaan mitään skaalaa, selain tekee sen itse, jos tekee.. vai mitä tarkoitat?

alussa [15.06.2006 14:39:22]

Lainaa #

Sooda, jos mä laitan nettiin jonkun kuvan, vaikka 1600x1200 nin se aukeaa kokonaan ja ruudussa ei näy kuin osa ja joutuu rullaamaan sitä eestaas. Tässä kun katoin sun kuvia niin ensin se latas ne kokonaan ja sitten sovitti ne ikkunan kokosiksi.
Toivottavasti mä osasin sen nyt selittää paremmin.

sooda [16.06.2006 12:31:24]

Lainaa #

No joissain selaimissa on sellanen skaalaustoiminto, että jos sillä avaa pelkän kuvan, niin se skaalaa sen näytölle. Skaalausta ei taas tapahdu jos kuva on jollain sivulla, eikä suoraan avattu.

alussa [17.06.2006 09:50:01]

Lainaa #

Hei, siinähän se...kun mä oon aina avannu sen thumbeista johkin taulukkoon tai vastaavaa nin siks se ei oo skaalannu...:(
No, seuraavaks mun pitää keksiä miten saan avattua kuvan tietyn kokosena.
Kiitti avusta Sooda!

tsuriga [30.06.2006 14:49:03]

Lainaa #

Tossa thumbbien luonnissa vois tiedostopäätteen ottaa talteen niin ei tartteis aina substr:ää vaivata. Ja löytyypä tuolta myös noita "$muuttuja" merkintöjäkin, joista joutaa nuo heittomerkit poies. Muuttujanimiäki vois vähä selvemmiks.. ja jos vielä saisit auringon pysymään piilossa kesän ajan. Tämmostä pientä.

sooda [30.06.2006 15:05:30]

Lainaa #

Korjailin tuonne vain yhden substr:n. Yhtään "$muuttuja" -merkintää ei omasta mielestäni ole, on niissä muutakin tekstiä mukana jos hipsuissa on. Lisäksi yks hassu huomio, että putka ilmeisesti epätykkää &lt;- ja &gt;-merkinnöistä, kun ei näytä niitä sellaisenaan vaan muuttaa suoraan ankannokiksi (kuten tuossa sivutuksessa).

Partahauki [23.07.2006 20:41:21]

Lainaa #

mitähän mulla puuttuu, lu uta ei tee thumppeja?? täysikokoiset kuvat kyllä näkyy kun painaa linnkkiä missä tumpin pitäis olla.

Partahauki [23.07.2006 20:42:39]

Lainaa #

hohhoh tulias typoa.. eli uusiksi: Mikähän mättää kun tuo ei tee thumbnaileja ollenkaan

Partahauki [23.07.2006 20:42:48]

Lainaa #

hohhoh tulipas typoa.. eli uusiksi: Mikähän mättää kun tuo ei tee thumbnaileja ollenkaan

SpaceMonkey [03.08.2006 15:04:08]

Lainaa #

Yhdistämällä tämän hienon galleria-skriptin PHPFileNavigaattoriin, saa hyvän ja helppokäyttöisen paketin: kuvat ladataan PHPFileNavigaattorilla (open source) ja sitten soodan galleria-skripti luo itse gallerian. PHPFileNavigaattorissa voi tiedostoille lisätä nimen ja selosteen. Tässä yksinkertainen skripti mitä voi käyttää esim. kuvatekstin hakemiseen PHPFileNavigaattorin tietokannasta.

Galleriassa voidaan kutsua index.php esim. kuvatekstin kohdalla:

echo haeKuvanOtsikko($kuva, $hak)

joka kutsuu vaikka incluudattua:

<?php

function haeKuvanOtsikko($kuvanNimi, $kansio) {

	//PHPGileNavigatorin root-tiedostosta riippuva hakemisto. Jos root-kansio on "/home/public_html/" niin gallerian ollessa osoitteessa "/home/public_html/galleria/" on niin oltava "./galleria/"
	$Polunalku= "./galleria/";

	$kansio = $Polunalku.$kansio."/";

	$db=mysql_connect ("localhost", "username", "salasana") or die ('I cannot connect to the database because: ' . mysql_error());
	mysql_select_db ("tietokanta", $db);

	//Valitaan tiedoston otsikko ja kansio
	$query = "SELECT pfn_palabras.palabra, pfn_directorios.directorio  ";
	$query = $query."FROM pfn_arquivos, pfn_arquivos_campos_palabras, pfn_palabras, pfn_directorios ";
	$query = $query."WHERE pfn_directorios.id = pfn_arquivos.id_directorio AND ";
	$query = $query."pfn_arquivos.arquivo like '%".$kuvanNimi."%' AND ";
	$query = $query."pfn_arquivos.id = pfn_arquivos_campos_palabras.id_arquivo AND ";
	$query = $query."pfn_arquivos_campos_palabras.id_palabra = pfn_palabras.id AND ";
	$query = $query."pfn_arquivos_campos_palabras.id_campo = 1";

	$result = mysql_query($query, $db);

	$num_results = mysql_num_rows($result);

	$tulos = " ";
	for ($i=0; $i < $num_results; $i++)
	{
		$row = mysql_fetch_assoc($result);

		//muodostetaan yksi merkkijono niistä joissa kansio täsmää
		if (stripslashes($row['directorio']) == $kansio) {
			$tulos = $tulos.' '.stripslashes($row['palabra']);
		}

	}

	mysql_free_result($result);
	mysql_close($db);

	return $tulos;

}

?>

PHPFileNavigaattori on espanjankielinen ohjelma (alunperin) joten myös tietokannan taulut ovat espanjaksi. SQL lauseesta: valitaan otsikko (palabra) ja hakemisto (directorio) kun kuvan nimi (arquivo) täsmää ja seloste (id_campo) on 1 (tiedoston otsikko, tai 2 eli seloste). Valittu tiedoston otsikko on jaettu välilyöntien kohdilta eri tietokannan riveille joten ne pitää yhdistää. En osannut tehdä toimivaa tiedostopolkuvertailua SQL-lauseeseen, joten se tehdään skriptissä vasta kuvatekstin muodostamisen yhteydessä.

Kaameaa php-koodausta. Varsinkin tuo tiedostopolkuvertailu pitäisi tehdä SQL-lausessa ja tuon PHPFilenavigaattorin root-hakemistonkin varmasti voisi kaivaa jostain sen tietokannasta.

Tontttu [11.09.2006 20:20:03]

Lainaa #

lainaus:

Mä oon niin ilkeä ja kerron .htaccessin:

Options -Indexes

Jotkut palvelimet ei näytä kansion sisältöö, jos ei oo kansiossa indexiä, toi koodi saa ne näkymään.


Mulla aukee kuvat suoraan thumbnailista originaliin, toisin kuin esimerkkisivulla. Miks? Eikä näytä olevan mitään kommentointimahdollistuuttakaan, kuten esimerkkisivulla.

Lehti [29.12.2006 09:49:51]

Lainaa #

Hei sooda, mahdikas galleria >:O

juha127 [23.11.2007 20:42:11]

Lainaa #

Upea galleriasofta. Pienenpienellä viilauksella: http://juhan.homelinux.net/kuvat/ :)

apsu [05.07.2008 10:29:15]

Lainaa #

Ei toimi!!!

Wee [02.09.2008 16:47:51]

Lainaa #

Evotat vaan -.-

siikamies [28.09.2009 20:18:23]

Lainaa #

Semmonen ongelma, että tyylitiedosto ei taida mulla toimia. Antakaa korjausvinkkejä: http://filut.heliohost.org/galleria/

Kirjoita kommentti

Muista lukea keskustelun ohjeet.
Tietoa sivustosta