18. november 2006 - 11:43Der er
35 kommentarer og 1 løsning
Opret thumbnail når image uploades
Hey Kan i hjælpe mig med følgende:
Jeg har et script der uploader billeder samt en beskrivelse af dem. Beskrivelserne og billedstien smides i en mysql database, mens selve billedet smides i biblioteket "upload" på serveren. Billederne uplodes i den størrelse, som brugeren uploder dem i.
Jeg har brug for et script, der samtidigt med, at billederne uploades og smides ind i db og bibliotek samtidigt opretter en thumbnail af den - thumben smides i biblioteket "thumbnail".
Jeg har afprøvet forskellige scripts, men uden held. Jeg kan simpelthen ikke finde et script der kan ovennævnte funktion
PHP kan benytte et ekstra library kaldet GD library. Det giver PHP mulighed for lave billeder i diverse formater, såsom PNG, JPG etc. Du kan kigge her: http://php.net/gd.
At få GD Lib til at lave et thumbnail er rimelig simpel - men måske har du fundet ud af det?
hæ hæ... nej jeg har ikke fundet ud af det. Jeg har godt læst en masse om GD men synes det er svært. Jeg vil gerne stykke et script sammen, der på een gang uploder og generer et thumnail billede.
Jeg tror jeg kan hjælpe med selve GD og thumbnail generering, men upload har jeg ikke brugt i lang tid. Men så vidt jeg husker så får du filens lokation et sted på serveren - og det er alt hvad du behøver egentlig.
Men ang. thumbnails så er der spørgsmålet om forhold mellem højde og bredde. Man kan sagtens sige at dine thumbnails skal være 40% af højde og bredde af original-billedet, men så vil hver thumbnail jo følge original-billedets højde-bredde forhold. Dette kan ødelægge et webdesign.
De thumbnails du ser er lavet med GD lib + en algoritme som tager højde for højde-bredde forskellene.
Nå, men hemmeligheden i simple thumbnails generering ligger i at tage det originale billede og lave en ny kopi hvor billedets højde og bredde er blevet skaleret ned.
<?php // Du får fat i filnavn og skalerings-grad i procent, her 50%: $filename = 'uploaded_file.jpg'; $percent = 0.5;
// her der får du fat i højde og bredde af billedet og skalerer disse værdier: list($width, $height) = getimagesize($filename); $newwidth = $width * $percent; $newheight = $height * $percent;
// imagecreatetruecolor() laver et nyt resource-object i // PHP, en speciel PHP datatype som bruges når man bruger // GD lib. $thumb er altså en resource som indeholder // en ren data-struktur til et nyt billede - det nye thumbnail // billede. Imagecreatefromjpeg() indlæser dit billede // som var det JPEG. Her forventes et JPEG billed. Der // findes funktioner til indlæsning af andre billede // formater. $source er et resource-object som // nu indeholder det uploadede billed: $thumb = imagecreatetruecolor($newwidth, $newheight); $source = imagecreatefromjpeg($filename);
// Magien ligger i at bruge imagecreateresized(). // Den modtager de to resource-objekter, // pixel koordinater i destination og kilde-billedet (her begge 0,0) // og de nye og gamle billede størelser. // Det den gør er simpelthen at lave en ny skaleret kopi // af det som ligger i $source og gemme det i $thumb. imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Her gemmes thumbnail billedet: imagejpeg($thumb, 'thumbnail_uploaded_file.php'); ?>
if(move_uploaded_file($_FILES['myFile']['tmp_name'], $curDir . $uploadDir . $file)) { mysql_query("INSERT INTO tbl_716418(filename,design,email,kategori,header,pris,comment,added) VALUES('".$file."','".$session->username."','".$email."','".$kategori."','".$header."','".$pris."','".$comment."',NOW())") or die(mysql_error()); $output .= 'Filen er uploadet<hr />'; } } } ?>
Jeg har forsøgt at sætte det ind forskellige steder men uden held. Jeg får også fejl på $filename = 'uploaded_file.jpg'; Den kan ikke få forbindelse til 'uploaded_file.jpg' ?????
Koden jeg skrev før skal ikke indsættes flere sted. Jeg burde have lavet en funktion så det gør jeg nu :)
Denne funktion modtager 2 argumenter: $filename som er den relative sti til det uploadede billede, og $percent som er skalerings-graden (standard 50%).
<?php function make_thumbnail($filename, $thumbs_dir, $percent = 0.5) { // her der får du fat i højde og bredde af billedet og skalerer disse værdier: list($width, $height) = getimagesize($filename); $newwidth = $width * $percent; $newheight = $height * $percent;
// imagecreatetruecolor() laver et nyt resource-object i // PHP, en speciel PHP datatype som bruges når man bruger // GD lib. $thumb er altså en resource som indeholder // en ren data-struktur til et nyt billede - det nye thumbnail // billede. Imagecreatefromjpeg() indlæser dit billede // som var det JPEG. Her forventes et JPEG billed. Der // findes funktioner til indlæsning af andre billede // formater. $source er et resource-object som // nu indeholder det uploadede billed: $thumb = imagecreatetruecolor($newwidth, $newheight); $source = imagecreatefromjpeg($filename);
// Magien ligger i at bruge imagecreateresized(). // Den modtager de to resource-objekter, // pixel koordinater i destination og kilde-billedet (her begge 0,0) // og de nye og gamle billede størelser. // Det den gør er simpelthen at lave en ny skaleret kopi // af det som ligger i $source og gemme det i $thumb. imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Her gemmes thumbnail billedet: imagejpeg($thumb, $thumbs_dir.'thumb_'.$filename.'_'.md5_file($filename).'.jpg'); } ?>
Jeg nævner også tidligere at funktionen modtager 2 argumenter. Den modtager faktisk 3 argumenter, stien til billed-filen, stien til thumbnail-mappen og en skalerings-faktor.
Hmm...ok. Jamen hvis du får fejlen "Fatal error: Call to undefined function: make_thumbnail()", så er det jo klart at PHP ikke kan finde funktionen "make_thumbnail", af en eller anden grund...jeg håber du er med så langt :)
function make_thumbnail($filename, $thumbs_dir, $percent = 0.5) { // her der får du fat i højde og bredde af billedet og skalerer disse værdier: list($width, $height) = getimagesize($filename); $newwidth = $width * $percent; $newheight = $height * $percent;
// imagecreatetruecolor() laver et nyt resource-object i // PHP, en speciel PHP datatype som bruges når man bruger // GD lib. $thumb er altså en resource som indeholder // en ren data-struktur til et nyt billede - det nye thumbnail // billede. Imagecreatefromjpeg() indlæser dit billede // som var det JPEG. Her forventes et JPEG billed. Der // findes funktioner til indlæsning af andre billede // formater. $source er et resource-object som // nu indeholder det uploadede billed: $thumb = imagecreatetruecolor($newwidth, $newheight); $source = imagecreatefromjpeg($filename);
// Magien ligger i at bruge imagecreateresized(). // Den modtager de to resource-objekter, // pixel koordinater i destination og kilde-billedet (her begge 0,0) // og de nye og gamle billede størelser. // Det den gør er simpelthen at lave en ny skaleret kopi // af det som ligger i $source og gemme det i $thumb. imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Her gemmes thumbnail billedet: imagejpeg($thumb, $thumbs_dir.'thumb_'.$filename.'_'.md5_file($filename).'.jpg'); } ?>
Som du kan se, så har jeg indsat definitionen af funktionen "make_thumbnail()" forneden i koden. Hvis du bare blindt kopierede den forrige kode jeg skrev uden funktionen, så er det klart det ikke virker...
:-( Så får jeg fejlen: Warning: imagejpeg() [function.imagejpeg]: Unable to open '/customers/kbh2000.dk/kbh2000.dk/httpd.www/thumbnails/thumb_/customers/kbh2000.dk/kbh2000.dk/httpd.www/upload/e0f04911da27e0633baa1a15b07b1a9c.jpg_9136aa2384a6dbab948cdae69240bf26.jpg' for writing in /customers/kbh2000.dk/kbh2000.dk/httpd.www/resize.php on line 136
Linie 136 er: imagejpeg($thumb, $thumbs_dir.'thumb_'.$filename.'_'.md5_file($filename).'.jpg');
Den smider jo både original billedet ind i biblioteket "upload" og thumbnailsene ind i "thumbnails"... kan det være det, der er problemet?
:-) Scriptet virker fint hvis jeg uploader små billeder - jeg har prøvet et billede af 20,0 kb... no problemo Men hvis jeg uploader lidt størrere billeder - fx 1,8 mb, så får jeg fejlmeddelsen:
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 10784 bytes) in /customers/kbh2000.dk/kbh2000.dk/httpd.www/resize.php on line 125
hvor linie 125 er: $source = imagecreatefromjpeg($filename);
Hmm mystisk. Den påstår at du en grænse for hukommelses-forbrug på 16MB. At imagecreatefromjpeg() skulle have sådan et forbrug ved indlæsning af et 1.8MB billede forstår jeg ikke.
Du kan evt. forsøge at forøge din hukommelses-grænse:
Hvis du vil have 32MB hukommelse som grænse på serveren: <?php ini_set('memory_limit', '32M'); ?>
Eller hvis du vil prøve med ingen grænse: <?php ini_set('memory_limit', '-1'); ?>
Det sidste kan dog helt sikkert tillade scripts som kan slå servere fuldstændig omkuld :)
Jeg må indrømme at jeg ikke er helt sikker på det. Ifølge http://dk2.php.net/manual/en/ini.core.php#ini.memory-limit så kan man sætte "memory_limit" fra PHP scripts (læg mærke til PHP_INI_ALL konstanten). Men jeg er ikke sikker på om eksempelvis php safe-mode, som sandsynligvis er aktiveret, kan gøre det umuligt at ændre på "memory_limit".
Men jeg forstår ikke fejlen. Jeg har ingen problemer med store filer i det gallery jeg har lavet (tror jeg ikke - ved ikke lige hvor store de filer egentlig er).
Een ting er at thumbnail billedet bliver smidt op i et bibliotek, men kan jeg også få smidt en henvisning til thumbmailbilledet op i samme database, som resten af informationerne smides op i.
Jeg har forsøgt at indsætte $thumb ind, men det virker ikke.
mysql_query("INSERT INTO tbl_716418(filename,thumb,design,email,kategori,header,pris,comment,added) VALUES('".$file."','".$session->username."','".$thumb"','".$email."','".$kategori."','".$header."','".$pris."','".$comment."',NOW())") or die(mysql_error());
Det kryptiske tal efter det oprindelige filnavn er en md5-hash af selve filens indhold. Du laver også selv en hash kan jeg se - måske af filnavnet? Det er noget jeg plejer at gøre met thumbnail billeder. Men måske er det ikke nødvendig når du selv har en hash det originale filnavn.
Nej jeg mener ikke det er nødvendigt, for det virker faktisk fint uden :-)
Jeg vil forsøge at få en henvisning til thumbnail billedet smidt op i en database - det får jeg også brug for hjælp til... hvis jeg smider yderligere 30 p oven i hatten, var det måske så noget du kunne hjælpe mig med?
Løsningen er vel relativt simpel. Det drejer sig vel bare om at få fat i thumb-nail filnavnet og sætte det ind i databasen. Men det er faktisk ikke nødvendigt.
Ved gallerier plejer jeg at tjecke om der eksisterer et thumbnail billede. Det kan jeg gøre da jeg ved hvad det eventuelle thumbnail-billede hedder hvis det eksisterer. Hvis den ikke eksiterer så opretter jeg den med gd lib.
Samtidig gør md5-hashen thumbnail-filnavnet unikt til det originale billede. Jeg plejer at udregne hash'en af hele filens indhold (med md5_file()). Men man kan også nøjes med at gøre det på filens navn.
Hash er en funktion jeg ikke er stødt på før nu... og derfor ikke noget jeg forstår ret meget af :-)
Jeg tror, at jeg vil forsøge mig med at smide en henvisning til thumbnailen ind i en database.
Jeg har prøvet mig frem, men uden held. Hvordan får jeg egentlig fat i thumbnail filnavnet? Hedder det $thumb eller $source eller noget helt 3???
Hvis det hedder $filename, kommer det vel til at kollidere med den anden $filename, som jo i forvejen smides i DB... altså den filename, som henviser til billedet i original størrelse som smides i biblioteket "upload".
Det med hash kan godt virke ret nyt og mærkeligt første gang man møder det. Matematisk handler det om at "mappe" en stor måske uendelig mængde til en endelig mængde (så vidt jeg husker). Dette lyder magisk og det er det egentlig også. Det kan ikke lade sig gøre fuldstændig. Men i praksis viser det sig ikke at betyde noget (igen så vidt jeg ved).
At udregne en hash af en fil indhold svarer til at man bruger filens indhold til at udregne et tal - en hashværdi. Dette er vores tilfælde de lange kryptiske sekvenser såsom a1500aee65bd48ab9a8880098c3f0e94. Ændrer man en enkel bit i filen så er hashværdien fuldstændig anderledes. MD5 er en ældre hash algoritme som stadig bruges eksempelvis ved download af filer. Se evt. http://dev.mysql.com/downloads/mysql/4.1.html. Her har de lagt de MD5 hash-værdier som de har udregnet. Downloader man filen kan man tjecke om ens hash-værdi af samme fil stemmer overens med den oplyst på hjemmesiden. Hvis den er helt anderledes så er der sansynligvis sket en fejl i fil-overførslen. Dette er vigtigt ved download af store system filer eksempelvis linux iso'er.
Nå men det var lidt om hashværdier. Jeg bruger som sagt dem til at få et navn til hver tænkelig billede som man vil lave en thumbnail af. Computeren udregner blot hash-værdien og bygger dynamisk thumbnail navnet.
Der lærte jeg noget nyt :-) Men hvis der ikke smides en henvisning til billedet ind i en database, hvordan kan jeg så bruge thumbnail billedet... altså hive thumbnail billedet frem og vise på det forskellige sider.
ideen er at du dynamisk kan udregne filnavnet for thumbnail-billedet for hver original billede. Du hiver blot billedets filnavn frem fra databasen og påfører eksempelvis "thumb_" foran filnavnet og md5-hash'en (med md5_file()) samt ".jpg" efter filnavnet. Dette gemmes i en variabel og du har filnavnet på thumbnail-billedet. Det er faktisk det jeg gør i mit tidligere svar hvor jeg gemmer navnet i $thumbname.
Hvergang du viser dit gallery med thumbnails så bliver disse thumbnail dynamisk genereret (for hvert billede). Ideen er først at lave filnavnet og derefter se om filen eksisterer (med file_exists()). Hvis den ikke ekisterer, så oprettes den med make_thumbnail().
Ok... det er lidt langhåret, men jeg tror godt at jeg kan følge dig :-)
Denne linie har jeg hevet ud af et script, der bla. viser et billede og dertilhørende tekst. echo "<img src='".$uploadDir="upload/" .$row['filename']."'>";
Ovennævnte linie hiver originalbilledet frem... hvis jeg nu skal have hevet thumbnailbilledet frem i stedet, så skal udloaddir selvfølgelig ændres til thumbnails, men det er ikke lykkes mig at sætte "thumb_" foran filnavnet og md5-hash'en (med md5_file()) samt ".jpg" efter filnavnet.
Læg mærke til at jeg determinerer strege med enkelt-apostrof, dette er som regel det nemmeste når outputtet er HTML. Men det er ikke nødvendigvis mere korrekt end doppelt-apostrof.
md5_file() kan ikke finde filen 7cacd349d1569366f597817c9aeba2b8.jpg :) Mere kan jeg ikke sige... jeg kan ikke se resten af stien i fejl-beskeden.
Det er ikke for at være fræk eller noget, men du må også meget gerne prøve selv at læse fejlbeskederne :) Men spørg du bare videre, jeg er her for at hjælpe.
kan jeg gå udfra at du er lidt ny indenfor PHP/programmering? PHP er godt at lærer programmering fra den har et rimelig simpelt debugging/fejlrapporterings system. Som regel melder PHP klart og tydelig om hvad problemet er.
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.