Avatar billede challenge Praktikant
28. november 2005 - 22:58 Der er 12 kommentarer og
2 løsninger

Billed resize med GDlib

Jeg har søgt lidt (læs: Meget!) efter emnet, men jeg kan absolut intet brugbart finde - Jeg ser kun en masse kryptiske koder, jeg intet ved hvad jeg skal gøre ved...

Sagen er, at jeg har et billedgalleri. Billederne henter jeg fra en sql database.

Billederne har jeg altså, men nu vil jeg gerne have en side der viser thumbnails af billederne. Denne side er også lavet, men thumbnails'ne har jeg siddet og resized i photoshop manuelt, hvilket jo ikke duer i længden, og slet ikke hvis jeg også vil have et upload-script.

Så GDlib strejfede mig, men jeg har ingen idé hvordan jeg bruger det...

Så mit spørgsmål er:
Hvordan kan jeg hente et billede ned fra min database, og derefter resize det "on the fly"?


Scriptet har i her:

billed.php (Filen med oversigt over billederne der skal resizes)

<?
  // Du kan bruge de oprindelige kommandoer ved at udfylde
  // felterne og fjerne kommentarene.
  $db = mysql_connect("localhost", "xxxxx", "xxxxx");
  mysql_select_db("xxxxx", $db);
  ?>
  <?
  // Hvis der ikke er valgt noget fra start
$order = $_GET['order'];
if ($order == "") $order = "dato";
?>
  <?
  // Hvis der ikke er valgt noget fra start
$sec = $_GET['sec'];
if ($sec == "") $sec = "DESC";
?>
<table cellspacing=0 cellpadding=0 class="spectext" width="583">
<tr>
<td class="spectext" width="583" align="center"><h1><font size="2">Ferrari billeder</font></h1></td>
</tr>
<tr>
<td height="10"></td>
</tr>
<tr>
    <td width="583" class="spectext">
        <table cellspacing=0 cellpadding=0>
            <tr><?php
$offset = (isset($_GET['offset'])) ? $_GET['offset'] : 0; // Hvis ikke $offset er sat, sættes den til 0
$pr_side = 9; // Antal resultater pr. side

// Henter poster fra databasen
$query = mysql_query("SELECT * FROM tabel ORDER BY id DESC LIMIT $offset,$pr_side") or die (mysql_error());
$i = 1;
while($data = mysql_fetch_array($query)) {
?>
                <td width="194" class="spectext" align="center"><? echo "<b><a href=billed_ex.php?id=". $data["id"] ." title='" . $data["titel"] . "' border=0>" . "<img src=" . $data["screen"] . " border=0>" . "</a></b>"; ?><br><b><? echo $data["titel"]; ?></b><br></td>

<?
    if(($i%3) == 0) {
        echo"</tr><tr>";
        }
    $i++;
}

while(($i%3) != 0) {
    echo"<td>&nbsp;</td>";
    $i++;
}
?>
<tr><td>
<?php
// Tæller antal poster i databasen
$antal = mysql_result(mysql_query("SELECT COUNT(*) FROM img_vid_db"),0);

$tal = 0;
$tal2 = $_GET['offset'] + 9;
$tal3 = $_GET['offset'] - 9;
$i = 2;
if ($_GET['offset'] != 0) echo "<tr><td class=btext2>&nbsp;&nbsp;&nbsp;&nbsp;Navigér:&nbsp;<a href=video.php?offset=". $tal3 .">&lt;</a>&nbsp;";
else echo "<tr><td class=btext2>&nbsp;&nbsp;&nbsp;&nbsp;Navigér:&nbsp;<b>&lt;</b>&nbsp;";
if ($_GET['offset'] == 0) echo "<b>1</b>&nbsp;";
else echo "<a href=billed.php?offset=0>1</a>&nbsp;";
while ($tal <= $antal / 9) {
$tal = $tal + 9;

if ($_GET['offset'] == $tal) echo "<b>".$i."</b>&nbsp;";
else echo "<a href=billed.php?offset=". $tal .">".$i."</a>&nbsp;";
if ($_GET['offset'] >= $antal / 9) echo "<b>&gt;</b></td></tr>";
else echo "<a href=billed.php?offset=". $tal2 .">&gt;</a></td></tr>";
$i++;
}
?>
            </tr>
        </table>
    </td>
</tr>
</table>

Jeg vil gerne give 200 point ekstra til en der vil hjælpe mig, hvis det er nødvændigt (altså 400 point i alt)

Håber at i kan hjælpe :)

mvh.

Stefan Helgason
Avatar billede kammeyer Nybegynder
29. november 2005 - 09:59 #1
max 200 point pr. spørgsmål.

Generelt ville jeg ofre diskpladsen til thumbnail billeder fremfor at generere billederne on-the-fly. Det kunne give serveren overflødigt ekstraarbejde / gøre den alt for tung i perioder.

GDlib virker fint hvis du ikke kommer ud for billedstørrelser der er større end datamængden PHP kan arbejde med. Normalt er den sat til 8 Mb data - og fylder din kode og billedet + det genererede thumbnail mere end 8 Mb til sammen, så er løsningen ikke GDlib - med mindre du har mulighed for at påvirke den størrelse på anden måde.

Hvor store er dine billeder?
Avatar billede jakobdo Ekspert
29. november 2005 - 12:50 #2
Jeg ville lave et thumbnail script.
Når den støder på et billede som ikke ahr thumbnail, så kunne den oprette det og gemme det på disken!
Så ville det ligge der til næste gang, dermed minimere du on-the-fly resizingen! (den vil kun ske på nye pics som endnu ikke er resizet og kun 1 gang)
Avatar billede caspers Nybegynder
29. november 2005 - 13:19 #3
Jeg bruger en meget langsom webserver, og laver derfor altid thumbnails sådan her:
ls *.JPG | xargs -iq convert q -thumbnail 320x200 thumb_q
Det tager naturligvis sin tid at komme igennem et par hundrede billeder, men derefter går det jo hurtigt at vise dem.
Avatar billede jakobdo Ekspert
29. november 2005 - 13:21 #4
Det kræver så lidt du har remote adgang til servere.
Avatar billede caspers Nybegynder
29. november 2005 - 13:36 #5
OK så kan du gruge denne funktion:

        function _resizeImageGD2($src_file, $dest_file, $new_size, &$imgobj) {
                if ($imgobj->_size == null) {
                        return false;
                }
                // GD can only handle JPG & PNG images
                if ($imgobj->_type !== "jpg" && $imgobj->_type !== "jpeg" && $imgobj->_type !== "png") {
                        return false;
                }

                // height/width
                $ratio = max($imgobj->_size[0], $imgobj->_size[1]) / $new_size;
                $ratio = max($ratio, 1.0);
                $destWidth = (int)($imgobj->_size[0] / $ratio);
                $destHeight = (int)($imgobj->_size[1] / $ratio);
                if ($imgobj->_type == "jpg" || $imgobj->_type == "jpeg") {
                        $src_img = imagecreatefromjpeg($src_file);
                } else {
                        $src_img = imagecreatefrompng($src_file);
                }
                if (!$src_img) {
                        return false;
                }
                $dst_img = imagecreatetruecolor($destWidth, $destHeight);
                imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $destWidth, (int)$destHeight, $imgobj->_size[0], $imgobj->_size[1]);
                if ($imgobj->_type == "jpg" || $imgobj->_type == "jpeg") {
                        imagejpeg($dst_img, $dest_file, $this->_JPEG_quality);
                } else {
                        imagepng($dst_img, $dest_file);
                }
                imagedestroy($src_img);
                imagedestroy($dst_img);
                return true;
        }
Avatar billede jakobdo Ekspert
29. november 2005 - 14:00 #6
Det ligner noget du bruger i en klasse..
Så måske mere noget i stil med:

function resize( $filename, $newfilename, $maxw, $maxh )
{
    $result = false;
    $srcim = imagecreatefromjpeg( $filename );
    $ow = imagesx( $srcim );
    $oh = imagesy( $srcim );
    $wscale = $maxw / $ow;
    $hscale = $maxh / $oh;
    $scale = ( $hscale < $wscale ? $hscale : $wscale );
    $nw = round( $ow * $scale, 0 );
    $nh = round( $oh * $scale, 0 );
    $dstim = imagecreatetruecolor( $nw, $nh );
    imagecopyresampled( $dstim, $srcim, 0, 0, 0, 0, $nw, $nh, $ow, $oh );
    $result = imagejpeg( $dstim, $newfilename, 85 );
    imagedestroy( $dstim );
    imagedestroy( $srcim );
    return $result;
}
Avatar billede challenge Praktikant
29. november 2005 - 20:33 #7
"max 200 point pr. spørgsmål."
Jeg skal prøve ;)

Tak for jeres svar allesammen, fedt at se at i gidder at tage jer tid! (misforstå mig nu ikke ;) )

kammeyer -
Kan godt se din pointe, men for mig holder det bare ikke i længden. Og da jeg også arbejdet på et upload-script, kan det jo ikke lade sig gøre :)

Caspers og jakobdo -
ja, nu står jeg så i den situation, som jeg forklarede ovenfor - Dér hvor jeg ser en masse kode, jeg ikke ved hvad jeg skal gøre af. Jeg vil meget gerne have givet jer pointene, men jeg ved ikke hvad jeg skal gøre herfra... Help? :)

Tak igen for svarene allesammen!

Stefan Helgason.
Avatar billede jakobdo Ekspert
29. november 2005 - 20:35 #8
Du beder dem som har hjulpet dig lægge et svar!
Når de så har svaret, kan du acceptere dem og give dem point.
Hvis du arbejder på et upload-script, så er det nemmeste at resize i upload processen.

Jeg har dog også lavet et script som resizer engang for alle, når billedet bliver forsøgt vist første gang, det må du også gerne se.
Avatar billede challenge Praktikant
29. november 2005 - 22:26 #9
"Du beder dem som har hjulpet dig lægge et svar!
Når de så har svaret, kan du acceptere dem og give dem point."
Jeg kan jo ikke give point når jeg ikke har forstået svaret fuldt ud,, vel?! ;)

Jo det eksempel du nævnte vil jeg da gerne se :)
Avatar billede jakobdo Ekspert
30. november 2005 - 09:43 #10
Noget i denne stil:

<?php

function resize( $filename, $newfilename, $maxw, $maxh )
{
    $result = false;
    $srcim = imagecreatefromjpeg( $filename );
    $ow = imagesx( $srcim );
    $oh = imagesy( $srcim );
    $wscale = $maxw / $ow;
    $hscale = $maxh / $oh;
    $scale = ( $hscale < $wscale ? $hscale : $wscale );
    $nw = round( $ow * $scale, 0 );
    $nh = round( $oh * $scale, 0 );
    $dstim = imagecreatetruecolor( $nw, $nh );
    imagecopyresampled( $dstim, $srcim, 0, 0, 0, 0, $nw, $nh, $ow, $oh );
    $result = imagejpeg( $dstim, $newfilename, 85 );
    imagedestroy( $dstim );
    imagedestroy( $srcim );
    return $result;
}

$dir = getcwd();

$allowExt = array("jpg");

// Open a known directory, and proceed to read its contents
if (is_dir($dir))
{
    if ($dh = opendir($dir))
    {
        $fileArray = array();
        while(($file = readdir($dh)) !== false)
        {
            $arr = explode (".", $file);
            $extension = end($arr);
            if(in_array($extension,$allowExt))
            {
                if(file_exists("thumb_" . $file) || preg_match('/^thumb_/', $file))
                {
                    ;
                }
                else
                {
                    resize($file, getcwd() . "/thumb_" . $file, 300, 300);
                }
               
                if(!preg_match('/^thumb_/', $file))
                {
                    $thumb = "thumb_" . $file;
                    $fileArray[$thumb] = $file;
                }
            }
        }
        closedir($dh);
    }
}

if(count($fileArray)>0)
{
    echo "<table id=\"centerTable\">\n";
    foreach($fileArray as $thumb => $file)
    {
        echo "<tr><td><a target=\"_blank\" href=\"" . $file . "\"><img src=\"".$thumb."\"></a></td></tr>\n";
    }
    echo "</table>\n";
}
else
{
    echo "Vi har ikke uploadet nogle billeder endnu, de kommer...";
}

?>
Avatar billede challenge Praktikant
30. november 2005 - 15:29 #11
Tak for det...
Men jeg får resultatet i min browser:

Vi har ikke uploadet nogle billeder endnu, de kommer...
Fatal error: Cannot redeclare resize() (previously declared in xxxxxxx:17) in xxxxxxxxxxx on line 17

Har prøvet at skifte $dir = getcwd(); ud med forskellige ting, men uden held.
Hvad gør jeg når billedet skal hesntes fra databasen?
Avatar billede caspers Nybegynder
30. november 2005 - 22:17 #12
Fint lille script.
Jeg har ikke undersøgt det, men hvis resize er et reserveret ord, skal du kalde funktionen noget andet.
Avatar billede jakobdo Ekspert
30. november 2005 - 22:41 #13
Du har funktionen resize med 2 gange!
Avatar billede challenge Praktikant
05. februar 2006 - 15:41 #14
Lukker.

Det strider lidt med mine principper, så derfor får caspers ½-delen af pointene...
Håber ikke at folk bliver sure :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester