Avatar billede Mik2000 Professor
27. januar 2009 - 14:50 Der er 26 kommentarer og
1 løsning

Billede skal med gdlib ændres i størrelsen

Nedenstående er en del af et script som uploader et billede efter man har valgt det i en formular.

Hvordan kan man sætte noget ind i den så den ændre størrelsen på billedet til at blive 500 i bredden og så højden blot passer til (så det ikke strækkes)
Det skal virke på jpg/jpeg, gif og png billeder

if (in_array($filendelse, $type_filer) && $max_str_kb > $_FILES['files']['size'][$key]) {   
  copy($_FILES['files']['tmp_name'][$key], $add);   
  chmod("$add",0777);

De 200 point er hvis du kan skrive en løsning til mig. Ellers hvis der kan linkes til hjælp gives 50-100 point afhængigt af kvaliteten.
Avatar billede jakobdo Ekspert
27. januar 2009 - 15:21 #1
Du kunne jo kigge på min resize artikel: http://www.eksperten.dk/artikler/1130
Og så tilrette koden:

$ow = imagesx( $srcim );
$oh = imagesy( $srcim );
$scale = 500 / $ow;
$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 );
Avatar billede jakobdo Ekspert
27. januar 2009 - 15:22 #2
Og så i stedet for at kalde:

copy($_FILES['files']['tmp_name'][$key], $add);
Kalder du:
resize( $_FILES['files']['tmp_name'][$key], $add, $quality=85 );
Avatar billede jakobdo Ekspert
27. januar 2009 - 15:22 #3
Og husk også at ret funktionen til så. :o)
Avatar billede tmi Nybegynder
27. januar 2009 - 17:47 #4
Du kan få en funktion jeg selv skrev en gang:

<?
    /**
    * Created by TMI
    * $in = array($img_width, $img_height, $gd_img_obj)
    * $out = array($width, $height, $outfile)
    * $bg = array(r, g, b). If false image will be cropped to fit
    **/
    function resizeImage($in, $out, $bg = false) {
        if (!$out[0]) {
            $prop = $in[1]/$out[1];
            $thumb = imagecreatetruecolor($width = $in[0]/$prop, $out[1]);
            imagecopyresampled($thumb, $in[2], 0, 0, 0, 0, $width, $out[1], $in[0], $in[1]);
            imagejpeg($thumb, $out[2], 100);
        } else if (!$out[1]) {
            $prop = $in[0]/$out[0];
            $thumb = imagecreatetruecolor($out[0], $height = $in[1]/$prop);
            imagecopyresampled($thumb, $in[2], 0, 0, 0, 0, $out[0], $height, $in[0], $in[1]);
            imagejpeg($thumb, $out[2], 100);
        } else {
            if ($bg) {
                $thumb = imagecreatetruecolor($out[0], $out[1]);
                $color = imagecolorallocate($thumb, $bg[0], $bg[1], $bg[2]);
                imagefill($thumb, 0, 0, $color);
                if ($in[0] > $in[1]) { // image is wider
                    $prop = $in[0]/$out[0];
                    imagecopyresampled($thumb, $in[2], 0, $out[1]/2-$in[1]/$prop/2, 0, 0, $out[0], $in[1]/$prop, $in[0], $in[1]);
                    imagejpeg($thumb, $out[2], 100);
                } else { // image is higher
                    $prop = $in[1]/$out[1];
                    imagecopyresampled($thumb, $in[2], $out[0]/2-$in[0]/$prop/2, 0, 0, 0, $in[0]/$prop, $out[1], $in[0], $in[1]);
                    imagejpeg($thumb, $out[2], 100);
                }
            } else {
                $thumb = imagecreatetruecolor($out[0], $out[1]);
                if ($in[0] > $in[1]) { // image is wider
                    $prop = $in[1]/$out[1];
                    imagecopyresampled($thumb, $in[2], 0, 0, $in[0]/2-$out[0]*$prop/2, 0, $out[0], $out[1], $out[0]*$prop, $in[1]);
                    imagejpeg($thumb, $out[2], 100);
                } else { // image is higher
                    $prop = $in[0]/$out[0];
                    imagecopyresampled($thumb, $in[2], 0, 0, 0, $in[1]/2-$out[1]*$prop/2, $out[0], $out[1], $in[0], $out[1]*$prop);
                    imagejpeg($thumb, $out[2], 100);
                }
            }
        }
    }
   
   
   
    // Eksempel:
    $image = $_FILES['img']['tmp_name'];
    $saveas = "images/gem/her.jpg";
   
    $newwidth = 500;
    $newheight = 0;
   
    $size = getimagesize($image);
    $img = imagecreatefromstring(file_get_contents($image));
    resizeImage(array($size[0], $size[1], $img), array(225, 0, $saveas));
   
?>
Avatar billede tmi Nybegynder
27. januar 2009 - 17:50 #5
Den kan altså både resize proportionalt til fast bredde eller fast højde, eller den kan skære billedet til så det bliver width X height eller den kan gemme det i width x height uden at skære det, hvis du angiver en baggrundsfarve.
Avatar billede tmi Nybegynder
27. januar 2009 - 17:52 #6
Og sidste linje skulle selvfølgelig være:

resizeImage(array($size[0], $size[1], $img), array($newwidth, $newheight, $saveas));
Avatar billede Mik2000 Professor
29. januar 2009 - 00:28 #7
Hej

Jeg har prøvet jakobdo's fordi den anden ikke så ud til at tage højde for png og gif.

Jeg har sat funktionen ind, og har byttet copy($_FILES['files']['tmp_name'][$key], $add);  ud med resize( $_FILES['files']['tmp_name'][$key], 500, 500, $add, $quality=90 );
De 2 500 er fordi den lavede en fejl med den manglede parametre.

Den laver ingen fejl når den kører men billedet er der ikke (men det er der når jeg bare bruger copy)

Har ikke lavet understående da jeg medsendte w og h
$ow = imagesx( $srcim );
$oh = imagesy( $srcim );
$scale = 500 / $ow;
$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 );

Kan du hjælpe med hvad der måske er galt?
... kan du også sige om det vil virke med PHP4?
Avatar billede jakobdo Ekspert
29. januar 2009 - 08:07 #8
Det bør virke med php4 også ja.
Prøv at smid en
if(resize(...))
echo 'Resize ok';
else
echo 'Resize !ok';
Avatar billede Mik2000 Professor
29. januar 2009 - 12:28 #9
Den siger Resize !ok - så der er gået noget galt. Men kan ikke se hvad for den skriver ikke noget

Er der noget jeg skulle have ændret i funktionen som jeg ikke har ændret

Linjen der kører den ser sådan ud:
resize( $_FILES['files']['tmp_name'][$key], 500, 500, $add, $quality=90 )

... og ved at add og $_FILES['files']['tmp_name'][$key] bør være gode nok, dade også bruges i copyfunktionen

Jeg ved quality nok også sættes til 85 i funktionen, men regner med den bare ignorere 90 ik

Funktionen ligger sådan her:
function resize( $filename, $newfilename, $maxw, $maxh, $quality=85 )
{
  $ext = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );
  switch($ext)
  {
    case 'jpeg':
    case 'jpe':
    case 'jpg':
      $srcim = imagecreatefromjpeg( $filename );
      break;
    case 'gif':
      $srcim = imagecreatefromgif( $filename );
      break;
    case 'png':
      $srcim = imagecreatefrompng( $filename );
      break;
    default:
      return false;
  }
  $ow = imagesx( $srcim );
  $oh = imagesy( $srcim );
  $wscale = $maxw / $ow;
  $hscale = $maxh / $oh;
  $scale = min( $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 );
  switch($ext)
  {
    case 'jpeg':
    case 'jpe':
    case 'jpg':
      imagejpeg( $dstim, $newfilename, $quality );
      break;
    case 'gif':
      imagegif( $dstim, $newfilename );
      break;
    case 'png':
      $png_q = floor( abs( $quality / 10 - 9.9 ) );
      imagepng( $dstim, $newfilename, $png_q );
      break;
    default:
      return false;
  }
  imagedestroy( $dstim );
  imagedestroy( $srcim );
  return file_exists($newfilename);
}
Avatar billede jakobdo Ekspert
29. januar 2009 - 12:45 #10
Og mappen er korrekt chmod'et ?
Avatar billede TommyB Nybegynder
29. januar 2009 - 12:52 #11
En lille sjov historie :
Jeg har prøvet lign. problem for en kunde på små restriktive hoteller som Surftown og Cliché.
Et billede uploaded fra bruger og fil gemt fra fx. resize gav ikke samme rettigheder, så løsningen fra faktisk at kopiere originalen ind hvor den nye udgave skal ligge, det bibeholder rettighederne, og så når du har skaleret det overskriver du med den færdige, og bibeholder rettighederne igen ;).

Men.. giver dig ikke mulighed for at lave file_exists(), men så kan du måske smide det i en temp-mappe og flytte ind i endelig mappe bagefter.

Du kan også have en tom fil med de rigtige rettigheder du kopierer ind og så overskriver til sidst med imagepng(), imagejpeg() eller lign.
Avatar billede jensgram Nybegynder
29. januar 2009 - 12:59 #12
Prøv

- resize( $_FILES['files']['tmp_name'][$key], 500, 500, $add, $quality=90 )
+ resize( $_FILES['files']['tmp_name'][$key], $add, 500, 500, 90 )
Avatar billede Mik2000 Professor
29. januar 2009 - 13:57 #13
Det er på en virtuel server (wampserver), med GDlib og åbne rettigheder. Så der burde ikke være problemer der.

Den laver samme fejl hvis man kun skriver 90

Jeg fandt en stor fejl. De stod forkert i rækkefølge. Så den er ændret til (add rykket før 500):
resize( $_FILES['files']['tmp_name'][$key], $add, 500, 500, $quality=90 )

Den modtager rigtigt nu. Har udskrevet værdierne i starten af funktionen og den skriver:
FILNAVN: C:\wamp\tmp\php7574.tmp
NYTFILNAVN: ../billeder/test.jpg
WIDTH: 500
HEIGHT: 500
QUALITY: 90

Men desværre er det samme fejl uden den ligger op
Avatar billede Mik2000 Professor
29. januar 2009 - 14:01 #14
Problemet må vel være noget med det er en tmp fil .... for så passer ext jo ikke. Men hvorfor / hvad gør jeg forkert?
Avatar billede TommyB Nybegynder
29. januar 2009 - 14:47 #15
Extension har reelt intet med indeholdet af filerne at gøre, det skal du ikke bekymrer dig om, du kan altid omdøbe dem til hvad du vil :)

Men nogle systemer tillader dig ikke at tilgå filer i /tmp mapperne med andet end move_uploaded_file() .. så det første du altid gør er at flytte din modtaget fil ind i en temp-fil og arbejder videre derfra.
Avatar billede jakobdo Ekspert
29. januar 2009 - 15:29 #16
tmp har ikke nogen filendelse nej.
Så du skal evt. starte med at move_upload_file() og bagefter kalde resize()
Avatar billede Mik2000 Professor
29. januar 2009 - 17:17 #17
Er det ikke det samme som at copy først og derefter kører resize på den fil der er så er lagt over?
Avatar billede jakobdo Ekspert
29. januar 2009 - 17:27 #18
Jo, det kan ud også.
Avatar billede Mik2000 Professor
29. januar 2009 - 17:28 #19
Ser ud til at virke:
copy($_FILES['files']['tmp_name'][$key], $add);
resize( $add, $add, 500, 500, $quality=90 );
Avatar billede jakobdo Ekspert
29. januar 2009 - 17:33 #20
Bare ret til:
resize( $add, $add, 500, 500);
Avatar billede Mik2000 Professor
29. januar 2009 - 17:36 #21
Mange tak for hjælpen. Tror at point må tildeles jakobdo - men selvfølgelig også en tak til alle jer andre der har skrevet :)
Avatar billede Mik2000 Professor
29. januar 2009 - 17:39 #22
Jeg har dog lige et enkelt spørgsmål.
Er det svært at ændre så den kun laver billeder om som er større end 500, således at mindre billeder ikke forstørres?
Avatar billede jakobdo Ekspert
29. januar 2009 - 17:47 #23
Tja, inden du kalder resize() kan du kalde getimagesize() og aflæse højde og bredde.
Kig mere på http://dk.php.net/getimagesize

og du får et svar.
Avatar billede jakobdo Ekspert
29. januar 2009 - 19:43 #24
Takker for point
Avatar billede Mik2000 Professor
29. januar 2009 - 20:33 #25
Takker for hjælpen. Fungere det hele, også med getimagesize :)
Avatar billede jensgram Nybegynder
31. januar 2009 - 14:23 #26
"Jeg fandt en stor fejl. De stod forkert i rækkefølge. Så den er ændret til (add rykket før 500):
resize( $_FILES['files']['tmp_name'][$key], $add, 500, 500, $quality=90 )"


Ja - det var hvad jeg forsøgte at kommunikere :)

- resize( $_FILES['files']['tmp_name'][$key], 500, 500, $add, $quality=90 )
+ resize( $_FILES['files']['tmp_name'][$key], $add, 500, 500, 90 )
Avatar billede Mik2000 Professor
31. januar 2009 - 15:07 #27
Hehe det har du da ret i, og det stod egenlig meet klart hehe :)
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