
เห็นคำถามใน “ชมรมคนทำเว็บ” ว่า การย่อรูปภาพจากเครื่องของ Client ก่อนที่จะทำการส่งให้ SERVER เพื่อบันทึกรูปภาพ เพื่อลดจะนวน Data Transfer สามารถทำได้หรือไม่ ผมจึงลองทำมาก็ใช้ได้ในระดับหนึ่งไปลองดูกันเลยครับ มี source code ให้ไปโหลดไปศึกษากันครับ
เรามาดูว่าเมื่อทำเสร็จแล้วจะเป็นแบบอย่างไรครับ
เริ่มจาก ใน ส่วน ui ที่เป็น html
1 ทำการ include js,css ที่จำเป็นสำหรับงานนี้เข้ามาครับ
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> // ดึง jquery <link rel="stylesheet" href="css/bootstrap.min.css" > // ดึง bootstarp <link rel="stylesheet" href="css/bootstrap-theme.min.css" > // ดึง bootstarp <script src="js/bootstrap.min.js"></script> // ดึง bootstarp
2 เป็นส่วนของ html ในการแสดงผลต่างๆ สำหรับ user ในการเลือก แสดงรูป และย่อขยายรูป
<body>
<div class="container" style="padding:25px;">
<div class="row">
<h3>ย่อรูปโดย html5 และ js</h3>
<div class="form-group">
<label for="sel1">เลือกรูป</label>
<input class="form-control" id="imagebroswer" type="file"> // input สำหรับเลือกรูป
</div>
</div>
<div id="ximage" style="display:none;">
<div class="row" >
<p style="padding:25px;">
ย่อขนาดตามที่ต้องการ<br>
<input type="range" id="size" min="48" max="1024"> // Slide สำหรับย่อขยายรูป
</p>
<div id="preview">
<canvas id="Canvas" ></canvas> // canvas สำหรับแสดงผลรูปภาพ
</div>
</div>
<div class="row">
<form method="post" action="upload.php">
<input type="hidden" value="" name="datastring" id="pdata"> // input เอาไว้เก็บค่ารูปภาพส่ง server
<input type="submit" value="submit"> // ปุ่ม submit ส่งค่าไป server
</form>
</div>
</div>
</div>
</body>
3 ในส่วนนี่จะเป็น js ที่ความคุมการทำงานทั้งหมด ซึ่งเป็นส่วนสำคัญ
$(document).ready(function(){
var canvas;
var context;
var imageObj;
$myslider=$('#size'); // select id slide เพื่อใช้ในการส่งค่า
// ดัก event เมื่อมีการเลือน slide
$myslider.on('change',function(){
var value=parseInt($(this).val()); // ดึงค่าจาก slide มาแปลงเป็นตัวเลขด้วย parseInt
var maxWidth = canvas.width;
var maxHeight = canvas.height;
var width = value;
var aspectW = width / maxWidth;
context.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = value;
canvas.height = (aspectW*maxHeight);
context.drawImage(imageObj, 0, 0,value,(aspectW*maxHeight));
$('#pdata').val(canvas.toDataURL());
// console.log($('#pdata').val());
});
function readURL(input) {
if (input[0].value != "") {
var reader = new FileReader();
reader.onload = function (e) {
createimage(e.target.result);
}
reader.readAsDataURL(input[0].files[0]);
}
}
function createimage(result){
canvas = document.getElementById('Canvas');
context = canvas.getContext('2d');
imageObj = new Image();
imageObj.onload = function() {
if(this.width>800){
var maxWidth = this.width;
var maxHeight = this.height;
var width = 800;
var aspectW = width / maxWidth;
this.width = 800;
this.height = (aspectW*maxHeight);
}
canvas.width = this.width;
canvas.height = this.height;
$myslider.attr({min:100,max:this.width}).val(this.width);
context.drawImage(imageObj, 0, 0,this.width,this.height);
};
imageObj.src = result;
}
$( "#imagebroswer" ).change(function() {
readURL($(this));
$("#ximage").show();
});
});
</script>
4 ส่วนนี้จะเป็นส่วนที่เกี่ยวกับ servier คือไฟล์ upload.php ใน source code คับ จะเกิดขึ้นหลังจาก user กดปุ่ม submit
if($_POST['datastring']!=''){
$data = $_POST['datastring'];
list($type, $imgstr) = explode(';', $data);
list(, $type) = explode(':', $type);
list(, $imgstr) = explode(',', $imgstr);
$im = imagecreatefromstring(base64_decode($imgstr));
if ($im !== false) {
header('Content-Type: '.$type);
//imagepng($im,"test.png"); // ตรงนี้เป็นส่วนที่จะเขียนไฟล์รูปลงใน server ผม comment ไว้ครับ
imagepng($im);
imagedestroy($im);
}
else {
echo 'An error occurred.';
}
}else{
echo 'no image';
}
สามารถดาวน์โหลด SOURCE CODE ไปศึกษาได้ที่นี่
สรุป
- การย่อรูปก่อนส่งไป server สามารถทำได้ แต่ถ้า upload รูปใหญ่ก็ทำให้เครื่อง client ช้าเหมือนกันครับ(หรือเครื่องเราไม่แรง)
- การย่อรูปแบบนี้อาจมีข้อดีคือลด data transfer
หากมีคำถามแนะนำอย่างไรสอบถามได้ครับ
อยากได้ output เป็นไฟล์ .jpg ที่ฝั่ง server เลยน่ะครับ
ตัวที่ได้ มัน save เป็นรูป แล้วอ่านไม่ออก
ต้องไฟล์ source code ไปวางใน server ก่อนครับ
ใน code ส่วนที่ 4 ที่เป็น php imagepng($im,”test.png”); ไฟล์จะ save test.png ใน server ครับ
คือผมไม่ต้องการ ปรับขนาด
ลบบรรทัดนี้ออกไป // Slide สำหรับย่อขยายรูป
แล้วให้ระบบทำงานอัตโนมัติ โดย width = 800
ลองรันดูขึ้น no image
ต้องปรับ code ยังไงครับ