เห็นคำถามใน “ชมรมคนทำเว็บ” ว่า การย่อรูปภาพจากเครื่องของ 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 ยังไงครับ