imagecopyresampled în PHP, poate cineva să explice acest lucru? (Programare, Php, Manipularea Imaginii, Gd)

Alex B a intrebat.

OK, credeam că am înțeles această funcție, dar am un blocaj mental complet în această privință.

Am vrut să creez miniaturi decupate de dimensiunea 75×75 din fotografii care sunt de 800×536.

funcția imagecopyresampled are 10 parametri posibili. am încercat mai întâi așa:

// Starting point of crop
        $tlx = floor(($width / 2) - ($new_width / 2)); //finds halfway point of big image and subtracts half of thumb.
        $tly = floor(($height / 2) - ($new_height / 2)); //gets centre of image to be cropped.

imagecopyresampled($tmp_img,$img,0,0,$tlx,$tly,$new_width,$new_height,$orig_width,$orig_height);

Aceasta găsește fiecare parte a jumătății din imaginea mare și o decupează. sau cel puțin așa am crezut. dar, de fapt, decupează un pic din imagine și lasă partea dreaptă și partea de jos în negru (probabil de la imagecreatetruecolor, mai devreme).

Am găsit o modalitate de a face ceea ce vreau, dar vreau să îmi explicați cum funcționează.

Acum am:

//Create thumbnails.
            $new_width = 75; //pixels.
            $new_height = 75;

            if($width > $height) $biggest_side = $width;   
            else $biggest_side = $height;   

            //The crop size will be half that of the largest side   
            $crop_percent = .5;   
            $crop_width   = $biggest_side*$crop_percent;   
            $crop_height  = $biggest_side*$crop_percent;

            $c1 = array("x"=>($width-$crop_width)/2, "y"=>($height-$crop_height)/2);

        //Create new image with new dimensions to hold thumb
        $tmp_img = imagecreatetruecolor($new_width,$new_height);

        //Copy and resample original image into new image.
            imagecopyresampled($tmp_img,$img,0,0,$c1['x'],$c1['y'],$new_width,$new_height,$crop_width,$crop_height);

o face perfect, micșorând imaginea și apoi decupând mijlocul, dar matematica mea nu este foarte clară și, de asemenea, cred că este cu siguranță că nu înțeleg pe deplin funcția imagecopyresampled.

poate cineva să mă ghideze prin ea? parametru cu parametru. în special ultimii doi. inițial am introdus lățimea și înălțimea imaginii originale, dar aceasta introduce 400 și 400 (jumătate din partea cea mai lungă). îmi cer scuze pentru vociferare. sper ca mintea mea să înțeleagă asta în curând 🙂

Alex

1 răspunsuri
Marc B

Este destul de simplu, documentat aici

Parametrii:

1) $dst_image, un handle GD valid reprezentând imaginea pe care doriți să o copiați INTO
2) $src_image, un mâner GD valid care reprezintă imaginea din care se copiază

3) $dst_x – decalajul X în imaginea de destinație în care doriți să plasați imaginea reeșantionată
4) $dst_y – decalajul Y, idem

5) $src_x – decalajul X în imaginea sursă din care doriți să începeți copierea
6) $src_y – decalajul Y, idem

7) $dst_x – lățimea X a imaginii recent reeșantionate în $dst_image
8) $dst_y – lățimea Y, idem

9) $src_x – lățimea X a zonei de copiat din $src_imagine
10) $src_y – lățimea Y, idem

Deci…

Aveți o imagine $src_imagine de 800×536 și o imagine $dst_imagine de 75×75

       $width = 800                                $new_width = 75
+-----------------------+                        +----+
|                       |                        |    |
|                       |                        |    | $new_height = 75
|                       | $height = 536          +----+
|                       |
|                       |
+-----------------------+

Se pare că vrei să iei partea din mijloc a imaginii sursă și să faci o miniatură din ea, nu? Această bucată de mijloc ar trebui să reprezinte jumătate din înălțimea & lățimea imaginii originale, așa că doriți:

$start_X = floor($width / 4); //  200
$width_Y = floor($height / 4); // 134

  200     400      200       
+-----------------------+
|     |          |      | 134
|-----+----------+------|
|     | This part|      | 268
|-----+----------+------|
|     |          |      | 134
+-----------------------+

$end_x = $start_X + (2 * $start_x) // 3 * $start_x = 600
$end_y = $start_Y + (2 * $start_y) // 3 * $start_y = 402

imagecopyresampled($src, $dst, 0, 0, $startX, $start_y, 75, 75, $end_x, $end_y);
                               a  b  c        d         e   f   g       h

a,b – să începi să lipești noua imagine în partea de sus-stânga a imaginii de destinație.
c,d – începeți să extrageți pixeli din imaginea originală la 200,134
e,f – faceți ca imaginea redimensionată să fie de 75×75 (umpleți miniatura)
g,h – oprește copierea pixelilor la 600×402 din imaginea originală

Acum, presupunând că doriți ca miniatura să fie complet umplută. Dacă doriți ca imaginea sursă să fie micșorată proporțional (astfel încât să aibă același raport înălțime/lățime ca și originalul), atunci va trebui să faceți niște calcule pentru a ajusta valoarea a,b și e,f parametrii.

Comentarii

  • wow, mulțumesc mult. desenele mă fac să înțeleg mult mai ușor! și atât de rapid, de asemenea. deci, folosești parametrii end_x și end_y pentru coordonatele de oprire, când manualul ( m-am uitat mult la asta) spune că este vorba de lățimea și înălțimea imaginii sursă. asta este destul de diferit de ceea ce ai spus tu. acum, ceea ce folosesc eu acum, care funcționează are 400×400 în end_x și end_y. deci asta înseamnă că ia o tăietură de 400×400 din centru și apoi o micșorează în 75×75? –  > Por Alex B.
  • când se spune „imagine sursă” pentru end_x/end_y, este vorba de capătul PIEȚEI din imaginea sursă cu care vrei să lucrezi. Dacă vrei să micșorezi întreaga imagine, atunci este vorba de înălțimea/lățimea imaginii originale. În caz contrar, este doar înălțimea/lățimea bucății pe care o tai. –  > Por Marc B.
  • corect, deci eu doar micșorez o bucată de 400 pe 400 din întreaga imagine și apoi iau pătratul de 75×75 din mijloc? cred că am înțeles. huzzah! –  > Por Alex B.
  • Nu, tu copiezi o bucată de 400×268 din imaginea originală, micșorezi copia la 75×75 și o lipești în imaginea de destinație, care se întâmplă să fie de 75×75. –  > Por Marc B.
  • dar făcând ca înălțimea = biggest_side * crop_percent, precum și lățimea, este 400 pe 400. cred că în felul tău va face asta, dar uitându-mă la cifrele mele este 400×400. dacă aș face în felul tău, al nostru este un dreptunghi, deci ar fi strivit în 75×75 –  > Por Alex B.