Πίσω στο ευρετήριο

Image resizing with php Posted: 09-Mar-2020 19:16 PM

php, javascript, html tutorial
Δες το Demo Κατέβασε τα αρχεία 2 downloads

Όταν ανεβάζουμε φωτογραφίες στο site μας καλό είναι να έχουμε διαφορετικά μεγέθη έτσι ώστε να σερβίρουμε το σωστό μέγεθος στην κατάλληλη περίπτωση.
Παρακάτω θα δούμε πως μπορούμε με την php να τροποποιήσουμε το μέγεθος των αρχείων που ανεβάζουμε στο μέγεθος που θέλουμε κρατώντας τις αναλογίες.

  • Θα χρειαστούμε ενα index.html για το html markup
  • Ένα αρχείο script.js για την javascript γιατί θα στείλουμε την φωτό στον server μέσω Ajax και formData()
  • Και ένα αρχείο script.php για τον κώδικα php.
  • Θα φτιάξουμε και δύο φακέλους έναν original-images/, και έναν resized-images/. Στον πρώτο τις αρχικές διαστάσεις των φωτογραφιών, και στον δεύτερο τις τροποποιημένες.

index.php


<body>
   
   <!-- Ειναι σημαντικό σε κάθε φόρμα που εχουμε file upload να εχουμε το attribute 
    (ιδιότητα) enctype="multipart/form-data" αλλιώς το αρχείο δεν θα ανέβει.   -->
   <form action="" method="post" enctype="multipart/form-data">

       <h2>Image resizing with php</h2>
      
      <!-- Σε αυτό το html tag θα εμφανίζεται η επιλεγμένη εικόνα μας -->
      <div class="image-placeholder">
         <!-- Μέσα από την javascript θα στοχεύσουμε το src="" για να
         προσθέσουμε την διεύθηνση(URL) της εικόνας μας. -->
         <img id="uploadPreview" src="" width="100%">
      </div>

      <fieldset>
         <legend>Choose image</legend>
          <!-- Η javascript συνάρτηση previewImage() θα τρέχει κάθε φορά που 
          θα πατάμε το Uload button της φόρμας. -->
          <input type="file" name="image" id="uploadImage" onchange="PreviewImage();" >
          <input type="submit" name="upload" value="Upload">
      </fieldset>
      
      <!-- Το html στοιχείο όπου θα δείχνουμε κάποιο σφάλμα, αν προκύψει -->
      <p class="error"></p>
      <p id="image-size"></p>    
      
   </form>
   
   <!-- Link στο javascript αρχείο. -->
   <script src="script.js"></script>  

script.js


function PreviewImage() {

   // Δημιουργούμε την μεταβλητή error στοχεύωντας το html στοιχείο με την class="error"
   // για να μη γράφουμε συνέχεια "document.querySelector('.error')".
   let error = document.querySelector('.error');

   // Καθαρίζουμε το error html στοιχείο σε περίπτωση που είχαμε κάποιο σφάλμα.
   document.querySelector('.error').style.display = "none";

   // Στοχέυουμε το input file στην html φόρμα, και με την files[0], παίρνουμε
   // τις πληροφορίες που θέλουμε για το αρχείο που επιλέξαμε, όπως το όνομα, το μέγεθος,
   // τον τύπο(jpg, png, κτλ). 
   // Η files μας έπιστρέφει έναν πίνακα, οπότε εμείς στοχεύουμε την πρώτη τιμή(value)
   // στον πίνακα με το κλειδί(key) [0]. 
   let file = document.getElementById("uploadImage").files[0];

   // Καλούμε το αντικείμενο FileReader()
   let reader = new FileReader();
   
   // Ή μέθοδος readAsDataURL() του αντικειμένου(object) FileReader(), διαβάζει τον 
   // δυαδικό κώδικα του αρχείου και τον επιστρέφει ως data URL. Για να διαβαστεί από
   // τον browser.
   reader.readAsDataURL(file);

   // Όταν διαβασει(onload) ο browser το αρχείο, χωρίς σφάλματα ...
   reader.onload = function (event) {
      // ... θα στοχεύσουμε το html img tag για να εμφανίσουμε την εικόνα μας.
      let preview =  document.getElementById("uploadPreview").src = event.target.result;
   };

   // Αν προκύψει σφάλμα από την μεριά του browser και δεν διαβαστεί σωστά το αρχείο ...
   reader.onerror = function(event){
      // ... θα επιστρέψουμε ένα μήνυμα στην html φόρμα μας.
      return error.innerHTML = 'Σφάλμα ανάγνωσης του αρχείου';
   }

   // Επικύρωση(validation) του αρχείου.   
   // Θα ελέγξουμε το μέγεθος(size) και τον τυπο(type).
   
   // Θα ορίσουμε το ανώτατο επιτρεπτό μέγεθος του αρχείου
   // σε 1 ΜΒ.
   let maxSize = 1024 * 1024; 

   // Θα φιάξουμε έναν πίνακα validTypes όπου θα εχουμε τους έγκυρους
   // τύπους των αρχείων.
   let validTypes = ["image/jpg", "image/jpeg", "image/png", "image/gif"];

   // Θα ελέγξουμε το μέγεθος του αρχείου.
   if(file.size > maxSize){
      // Εαν το αρχείο είναι μεγαλύτερο απο το επιτρεπτό όριο θα τυπώσουμε
      // το σφάλμα στην οθόνη και θα τερματίσουμε την ροή.
      error.innerHTML = `Το αρχείο υπερβαίνει το ${maxSize / 1024 / 1024}MB`;
      return false;
   }

   // Θα ελέγξουμε τον τύπο του αρχείου.
   // Εαν ο τυπος του αρχείου δεν υπάρχει μέσα στον πίνακα validTypes[]
   // και εδω θα τυπώσουμε το ανάλογο μήνυμα σφάλματος.
   if(!validTypes.includes(file.type)){
      // Μύνημα σφάλματος.
      error.innerHTML = "Μη έγκυρος τύπος αρχείου";
      return false;
   }else{
      // το αρχείο είναι εγκυρο ...  
   }
}

// Στοχέυουμε και παρακολουθούμε την φόρμα για να πίασουμε το submit event
document.querySelector('form').addEventListener('submit', function(e){
   // αποτρέπουμε τον browser να εκτελέσει την εξ ορισμού ενέργεια της φόρμας.
   e.preventDefault();
   
   // Ελέγχουμε αν έχει επιλεγεί κάποιο αρχείο.
   if(document.getElementById("uploadImage").files.length == 0){
      document.querySelector('.error').style.display = "block";
      document.querySelector('.error').innerHTML = "No image selected";
      return false;
   }

   // Με το αντικείμενο formData('εισάγουμε την φόρμα ως παράμετρο') και Παίρνουμε
   // τις τιμές της φόρμας. Εδώ παίρνουμε το αρχείο. 
   let formdata = new FormData(document.forms[0]);
   
   // Θα προσθέσουμε μια τιμή 'image_upload' μόνο και μόνο για να 
   // τσεκάρουμε με την php αν η φόρμα εστάλη. 
   formdata.append('image_upload', 'true');  

   // Στέλνουμε ενα ajax request στον server με το αρχείο που
   // πήραμε απο την formData().
   let http = new XMLHttpRequest();
         
         http.open('post', 'script.php', true);
         http.send(formdata);
         
         http.onreadystatechange = function(){
            if(this.readyState == 4 && this.status == 200){
               let response = JSON.parse(this.responseText);
               // Δεν περιμένουμε απάντηση από τον server.            
            }
         }      
});
  

Για περισότερες πληροφορίες πάνω στίς συναρτήσεις που χρησιμοποιήσαμε θα βρείτε στα παρακάτω links.

script.php


<?php
	// !Σημέιωση: σε αυτό το παράδειγμα δεν θα επικυρώσουμε(validation) το
	// αρχείο της εικόνας, θα δούμε μόνο πως μπορούμε να αλλάξουμε τις
	// διαστάσεις στις τιμές που θέλουμε.

	/*Πρώτα απ όλα πρέπει να τσεκάρουμε αν η javascript μας έστειλε
	τα δεδομένα με την formData()*/
	if(isset($_POST['image_upload'])){
			
		// εφόσον τα δεδομένα είναι εδω θα χρειαστούμε το όνομα, τον τύπο
		// και την προσωρινή αποθηκεύση.
		$name = filter_var($_FILES['image']['name'], FILTER_SANITIZE_STRING);
		$temp = $_FILES['image']['tmp_name'];
		$type = $_FILES['image']['type'];

		/*έχουμε δυο φακέλους στον server, στον ένα θα αποθηκεύουμε την εικόνα
		στις αρχικές τις διαστάσεις('original-images'), και στον δεύτερο μετά
		την τροποποίηση της*/
		$orig_folder = "original-images/";
		$res_folder = "resized-images/";

		/*Θα μετακινήσουμε την εικόνα απο τον προσωρινό φάκελο της στον
		original_images/*/
		move_uploaded_file($temp, $orig_folder.$name);

		/*Τώρα πρέπει να πάρουμε τις αρχικές διαστάσεις και να τις ορίσουμε
		σε μεταβλητές για να τις διαχειριστούμε.*/		
		
		// Η getimagesize() μας επιστρέφει έναν πίνακα με τις τιμές της εικόνας.
		$file = getimagesize("original-images/".$name);
		// Τα πρώτα δυο πεδία είναι το πλάτος και το υψος (width, height).
		$orig_width = $file[0];
		$orig_height = $file[1];

		/*χρειαζόμαστε τις αναλογίες της εικόνας ώστε μετά την τροποποίηση, να μην
		υπάρχει παραμόρφωση.
		Αυτό θα γίνει αν διαιρέσουμε το πλάτος με το ύψος. πχ θα πάρουμε έναν 
		αριθμό 1.6 
		*/
		$aspect_ratio = $orig_width / $orig_height;
		
		// δηλώνουμε το width που θέλουμε.
		$new_width = 600;
		
		/*Και το ύψος θα υπολογίζεται αυτόματα διαιρώντας το νέο πλάτος 
		με τον αριθμό αναλογίας*/ 
		$new_height = $new_width / $aspect_ratio;
		
		// Ανάλογα με τον τύπο της εικόνας θα δημιουργήσουμε ενα αντίγραφο στην μνήμη.
		if($type == 'image/jpg' || $type == "image/jpeg"){
			$src = imagecreatefromjpeg("original-images/".$name);
		}elseif ($type == "image/png"){
			$src = imagecreatefrompng("original-images/".$name);
		}elseif ($type == "image/gif") {
			$src = imagecreatefromgif("original-images/".$name);
		}

		/*Εδώ θα δημιουργήσουμε έναν προσωρινό καμβά με το νέο πλάτος(width) 
		και το νέο υψος(hight) που δηλώσαμε παραπάνω*/
		$temp = imagecreatetruecolor($new_width, $new_height);
		
		/**
		 * Η imagecopyresampled() δέχεται 10 παραμέτρους και δείχνει περίπλοκη, 
		 * αλλά δεν είναι.
		 * Παράμετρο 1. $temp - είναι ο προσωρινός καμβάς ενα placeholder 
		 * με τις νέες διαστάσεις.
		 * Παράμετρο 2. $src - είναι το αντίγραφο στήν μνήμη που φτιάξαμε
		 * παραπάνω με την imagecreatefrom*
		 * Παράμετρο [3,4,5,6] Τα τέσσερα μηδεν είναι οι συντεταγμένες, που ξεκινάνε από το πάνω
		 * αριστερό σημείο της φωτό
		 * Παράμετρο [7] είναι το νέο πλάτος.
		 * Παράμετρο [8] είναι το νέο ύψος.
		 * Παράμετρο [9,10] είναι οι αρχικές διαστάσεις.
		 * Η imagecopyresampled() θα φτιάξει ένα προσωρινό αρχείο με τις παραμέτρους που
		 * της έχουμε δηλώσει. 
		*/
		 imagecopyresampled($temp, $src, 0, 0, 0, 0, $new_width, $new_height, $orig_width, $orig_height);

		/* Και το τελευταίο στάδιο είναι να πάρουμε το προσωρινό αρχείο της imagecopyresampled()
		 * και να δημιουργήσουμε την φωτό με τις νέες διαστάσεις.
		 * Kαι εδω αναλογα με τον τύπο της εικόνας θα τρέξουμε την ανάλογη function.
		 * Ανεξάρτητα απο τον τυπο της εικόνας και οι τρείς συναρτήσεις δέχονται τρέις
		 * παραμέτρους [1] το προσωρινό αρχείο, [2] τον φάκελο που θα αποθηκέυσουμε την φωτό
		 * [3] την ποιότητα της εικόνας.
		 * Για την jpeg και την gif οι τίμες είανι απο 0 - 100
		 * Για την png οι τιμές είναι από 0 - 10, όσο χαμηλώνει η τιμή τόσο χάνεται η 
		 * ποιότητα αλλά έχουμε και μικρότερο μέγεθος αρχείου.
		*/
		if($type == 'image/jpg' || $type == "image/jpeg"){
			imagejpeg($temp, $res_folder.$name, 80);
		}elseif ($type == "image/png"){
			imagepng($temp, $res_folder.$name, 8);
		}elseif ($type == "image/gif") {
			imagegif($temp, $res_folder.$name, 80);
		}
	}
  

Για περισότερες πληροφορίες πάνω στίς συναρτήσεις που χρησιμοποιήσαμε θα βρείτε στα παρακάτω links.

Σχόλια και ερωτήσεις μέσω facebook

Παρόμοια php tutorials

Image upload with php 17-Feb-2020 18:17 PM Σε αυτό το tutorial θα ανεβάσουμε μια φωτό στον server, και θα επικυρώσουμε (validate) αν η φωτό είναι έγκυρη.
Uploading an article with image 01-Mar-2020 22:13 PM Έχουμε μια φόρμα με τρία πεδία, τίτλο,άρθρο, και εικόνα, θα ανεβάσουμε την εικόνα στον server και θα εισάγουμε τα στοιχεία σε μια mysql βάση. Contact form validation with php 16-Mar-2020 00:54 AM Θα επικυρώσουμε μια φόρμα επικοινωνίας με php, και θα εισάγουμε τις τιμές σε μια βάση δεδομένων. Register form with php and ajax 24-Feb-2020 16:39 PM Εχουμε μια φόρμα εγγραφής στην οποία τα δεδομένα θα σταλούν με Ajax στο php αρχείο για επικύρωση. Image resizing with php 09-Mar-2020 19:16 PM Ενα php script για να τροποποιούμε τις διαστάσεις των φωτόγραφίων κατά το upload.

css Tutorials

Responsive grid layout 04-Mar-2020 17:15 PM Έχουμε μια responsive ιστοσελίδα που προσαρμόζεται σε όλες τις οθόνες Resposive navbar with css and javascript 05-Mar-2020 21:24 PM Ένα responsive οριζόντιο μενού πλοήγησης για μικρή και μεγάλη οθόνη, με css και λίγη javascript. Sticky navbar με css και javascript 28-Feb-2020 18:32 PM Έχουμε ένα οριζόντιο μενού όπου θα κολλάει στήν αρχή της σελίδας όταν κάνουμε scroll. Highlight selected menu page 12-Mar-2020 11:56 AM Έχουμε ένα οριζόντιο μενού όπου θα αλλάζουμε το background-color του link στην επιλεγμένη σελίδα.

javascript Tutorials

Autofill select combo box 27-Feb-2020 00:10 AM Θα δούμε πως μπορούμε να συνδυάσουμε δυο select drop-down menu έτσι ώστε επιλέγοντας το πρώτο να δίνουμε τις ανάλογες τιμές στο δεύτερο. Image preview with javascript 19-Feb-2020 16:04 PM Άμεση απεικόνιση της εικόνας σε file upload ενέργεια javascript and css slideshow 21-Feb-2020 01:27 AM Slideshow με fade effect, κείμενο, cta button, και responsive design γραμμένο σε css και javascript Show hide password with javascript 10-Mar-2020 23:28 PM Ένα javascript που εμφανίζει τα γράμματα όταν πληκτρολογούμε στο πεδίο password.

webDev Αναφορές

PHP Net Το σπίτι της php είναι η πιο έγκυρη πηγή εκμάθησης. Javascript Μozilla MDN web docs Τα πάντα για την Javascript. Όρεξη να έχεις να διαβάζεις. CSS Μozilla MDN web docs Απο βασικά styles εως animation, εδω θα τα μάθεις όλα. Programming Notes for Professionals Μια φοβερή συλλογή από PDF αρχεία, από Android εώς C++. Αξίζει να κατεβάσετε και να μελετήσετε τα αρχεία.

PHPDev Tutorials | Site developed by PHPDev.gr Visit PHPDev

scrollTo('top')