Όταν ανεβάζουμε φωτογραφίες στο 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