พบกับบทความเกี่ยวกับคอมพิวเตอร์และ programming ได้ที่ http://articles.modoeye.com | บล็อกอาหาร
PHP development / อยากทราบวิธี Resize รูปครับ
merious
merious
Thu 11 May 2006 17:52:08

คือ ตอนนี้ผมทำเว็บอยู่เว็บนึง ซึ่งมี Community เก็บ รูป,ข้อความ

และผมจะดึง จากฐานข้อมูลมาไว้ที่ index ซึ่งก็ดึงได้นะครับและ Resize แบบ html โดยกำหนด w,h ได้ แต่เวลาโหลดมันช้ามากครับ ผมเลยอยากทราบวิธีการ Resize รูป แบบถ้ามีการโพสข้อความ ก็จะเก็บรูปเล็ก(ไว้โชว์ index) และรูปใหญ่(ไว้โชว์ข้างใน) ซึ่งผมเก็บไฟล์รูปภาพลง ฐานข้อมูลโดยตรงและเวลาใช้ก็ดึงออกมาโดยตรง

ผมลองศึกษาวิธี Resize มานานพอสมควร แต่ไม่เข้าใจเลยครับ GetimageSize() อะ

แล้วผมจะต้องทำยังไงให้ เวลาโพสรูปป๊าบบ แค่รูปเดียว ก็จะแบ่งเป็น 2 รูปเลย โดยที่รูปแรกผ่านการ resize และรูปที่ 2 เป็นรูปเต็ม

เวลาโหลดหน้า index จะได้ไม่โหลดนานครับ

ใครรู้วิธีช่วยบอกทีนะครับ ยิ่งอ่านยิ่งไม่เข้าใจ อยากให้ใครซักคนมาอธิบาย ทำโปรแกรมคนเดียวนี่เหนื่อยจิงๆเลยครับ T_T

นี่เว็บผมคับ http://t-memorail.com/

Administrator
Thu 11 May 2006 18:31:26
การ Resize Image นั้นก่อนอื่นต้องทำการหาขนาดรูปเก่าก่อนครับ ใช้ getimagesize() นั่นล่ะครับ เช่น

list($width, $height, $type, $attr) = getimagesize($_FILES["userfile"]["tmp_name"]);

จากนั้นก็หา Ratio ครับเพื่อ Resize แบบ Aspect Ration

$maxDime = 400;
$newSize = 0;

if($width > $maxDime){
    $newSize["width"] = $maxDime;
    $newSize["height"] = ($maxDime / $width) * $height
}elseif($height > $maxDime){
    $newSize["height"] = $maxDime;
    $newSize["width"] = ($maxDime / $height) * $width;
}

จากนั้นก็สร้าง Image Resource มารองรับรูปใหม่ที่ทำการ resize แล้ว
$destImg = imagecreatetruecolor($newSize["width"], $newSize["height"]);

ทำการ copy รูปภาพจาก Source เก็บไว้เป็น image resource
$srcImg = imagecreatefromjpeg($_FILES["userfile"]["tmp_name"]);

ทำการ copy resource จาก source ลง Image resource ที่สร้างไว้พร้อมทั้ง Resize
imagecopyresized($desImg, $srcImg, 0, 0, 0, 0, $newSize["width"], $newSize["height"], $width, $height);

จากนั้นก็ทำการ save ไฟล์
imagejpeg($desImg, "files/".$_FILES["userfile"]["name"], 80);

ตรงที่ผมทำการ Highlight นั้นเป็นฟังก์ชั่นเฉพาะ JPEG เท่านั้น คุณสามารถทำการตรวจสอบชนิดของไฟล์ได้จาก $type ที่คืนค่ามาจากฟังก์ชั่น getimagesize() โดยเทียบจากชนิดของไฟล์ ได้จากค่าของ $type ตาม Array ข้างล่าง รวมไปถึงสามารถตรวจสอบได้ว่าเป็นไฟล์ที่อนุญาตให้ upload ได้หรือไม่

$types = array(
       1 => 'GIF',
       2 => 'JPG',
       3 => 'PNG',
       4 => 'SWF',
       5 => 'PSD',
       6 => 'BMP',
       7 => 'TIFF(intel byte order)',
       8 => 'TIFF(motorola byte order)',
       9 => 'JPC',
       10 => 'JP2',
       11 => 'JPX',
       12 => 'JB2',
       13 => 'SWC',
       14 => 'IFF',
       15 => 'WBMP',
       16 => 'XBM'
   );

ส่วนถ้าต้องการทำการ Resize สองขนาดอาจจะเขียนทั้งหมดเป็นฟังก์ชั่น แล้วทำการเรียกใช้ 2 ครั้งโดยการระบุขนาดใน argument ก็ได้ครับ
merious
merious
Thu 11 May 2006 18:47:45
โอ้โหเว็บมาสเตอร์ตอบเร็วจัง เด่วจะลองทำดูคับ
merious
merious
Thu 11 May 2006 19:10:23
แล้วถ้าต้องการเก็บไฟล์ใหม่ที่ resize ลง ฐานข้อมูล จะได้มั้ยครับ
merious
merious
Thu 11 May 2006 19:12:37

// คือ ลงฐานข้อมูล ฟิล เดียวกับ ไฟล์รูปเก่า แบบไฟล์เก่า ฟิล เป็น image และไฟล์ใหม่ ฟิล เป็น image_resize

ฟิลก็จะเป็น

id - name - note - image - image_resize

ทำแบบนี้ได้มั้ยครับ

Administrator
Thu 11 May 2006 20:04:23
ทำได้ครับ
แก้ไขตรง imagejpeg() ครับ โดย
เริ่มทำการ buffer image stream ครับด้วย

ob_start();
imagejpeg($desImg);
$binData = ob_get_contents();
ob_end_clean();

จากนั้นก็ทำการ addslashes() เพื่อใส่ลง mysql เช่น
mysql_query("INSERT INTO(..., image_resize) VALUES(....., '".addslashes($binData)."')");

ข้างบนผมลืมไปว่าต้องสั่ง imagedestroy() ให้กับตัว image resource ทุกตัวด้วยครับ

ผมขอแจ้งข้อเสียของระบบนี้นะครับ
การทำการ resize image นั้นจะใช้พลัง cpu มากกว่าปกติอยู่แล้ว โดยยิ่งทำการ buffer image ด้วยก็จะใช้งานทรัพยากรของระบบเพิ่มขึ้นอีก และยังไม่การบันทึก image ลงใน db อีกจะทำให้เครื่องทำงานหนักมากครับทั้งตอนบันทึกและตอนเรียกแสดงผล ถ้าเป็นไปได้ควรทำการบันทึกลงบน disc ข้อมูลปกติดีกว่าครับ ลดการทำงานของเครื่องลงได้เยอะครับ
merious
merious
Thu 11 May 2006 20:51:04

แล้วถ้าจะ getimagesize() จาก ฐานข้อมูล ทำยังไงหรอครับ

T_T ขอบคุนมากๆนะพี่เว็บมาสเตอร์ ผมรบกวนพี่มากไปเปล่าคับ

Administrator
Thu 11 May 2006 23:08:42
ผมเข้าใจว่าทำโดยตรงไม่ได้นะครับ (เท่าที่ลอง) แต่ถ้าเขียนไฟล์เพื่อแสดงรูปภาพไว้แล้วทำการเรียก getimagesize() ผ่าน script นี้น่าจะได้ครับ เช่น

getimagesize("viewImage.php?id=1234");

ประมาณนี้ครับ
merious
merious
Thu 11 May 2006 23:18:23

อ๋อ เข้าใจแล้วครับ โอ้ว แม่เจ้า ขอบคุนพี่มากๆเลยครับไม่รบกวนพี่แล้วคับ ^_^

เด่วผมต้องโปรโมทเว้บนี้ให้เพื่อนๆซะละ เว็บมาสเตอร์มีความรับผิดชอบมากครับ ถามไปตอบมาได้อย่างรวดเร็วจิงๆ ^_^

merious
merious
Thu 11 May 2006 23:48:58
ข้างบนผมลืมไปว่าต้องสั่ง imagedestroy() ให้กับตัว image resource ทุกตัวด้วยครับ  <<< แปลว่าไรคับพี่ผม งงทำไมทำไม่ได้ง่า T_T
Administrator
Thu 11 May 2006 23:59:17
$srcImg = imagecreatefromjpeg("img.jpg");

imagedestroy($srcImg);

เนื่องจากการใช้งาน GD Library เข่นการสร้าง Image Resource ข้างบน จะมีการใช้งานหน่วยความจำของระบบ ดังนั้นเมื่อเลิกใช้งานแล้วควรทำลาย image resource นั้นๆด้วยครับเพื่อคืนหน่วยความจำให้ระบบ เหมือน mysql_free_result() นั่นล่ะครับ
merious
merious
Fri 12 May 2006 00:01:37

Warning: imagecreatetruecolor(): Invalid image dimensions in c:\appserv\www\t-memorial\community\post_testresize.php on line 151

Warning: imagecopyresized(): supplied argument is not a valid Image resource in c:\appserv\www\t-memorial\community\post_testresize.php on line 153

ขึ้นแบบนี้เลยคับทั่น

merious
merious
Fri 12 May 2006 00:03:36

//จะทำการ resize ภาพที่ได้รับมาเพื่อแสดงหน้า index
mysql_connect($host,$user,$passwd);
$sql = "select * from webboard_data where Category='webboard' order by No DESC limit 0,1";
$result = mysql_db_query($dbname,$sql);
$NRow = mysql_num_rows($result);
while ($row = mysql_fetch_array($result)) {
$No = sprintf("%05d",$row["No"]);
$No = $No+1;

list($width, $height, $type, $attr) = getimagesize($_FILES["showimage.php?table=data&No=$No"]);
$maxDime = 400;
$newSize = 0;
if($width > $maxDime){
    $newSize["width"] = $maxDime;
    $newSize["height"] = ($maxDime / $width) * $height;
}elseif($height > $maxDime){
    $newSize["height"] = $maxDime;
    $newSize["width"] = ($maxDime / $height) * $width;
}
$destImg = imagecreatetruecolor($newSize["width"], $newSize["height"]);
$srcImg = imagecreatefromjpeg($_FILES["showimage.php?table=data&No=$No"]);
imagecopyresized($desImg, $srcImg, 0, 0, 0, 0, $newSize["width"], $newSize["height"], $width, $height);
//save ไฟล์ลงดาต้าเบส
ob_start();
imagejpeg($desImg);
$binData = ob_get_contents();
ob_end_clean();

mysql_query("INSERT INTO( Image_resize) VALUES( '".addslashes($binData)."')");

}

ผมทำไรผิดเปล่าฮะ รันแล้วไมได้ตลอดเลย T_T

Administrator
Fri 12 May 2006 00:24:22
$destImg = imagecreatetruecolor(round($newSize["width"]), round($newSize["height"]));

ถ้าไม่ได้ ลองทำการ print_r($newSize) ดูครับว่ามีค่าหรือไม่ ซึ่งถ้าไม่มีค่าใดๆ ให้ลองทำการตรวจสอบตัวแปร $width, $height ดูครับ เนื่องจากอาจจะมีปัญหาตั้งแต่ getimagesize() ไม่ได้ครับ
merious
merious
Fri 12 May 2006 02:55:20

พี่คับ แบบนี้เป็นไงคับ

$max_x = 97;
$max_y = 97;
$size = Getimagesize($img2);
$x=$size[0];
$y=$size[1];
$x_ratio=$max_x / $x;
$y_ratio=$max_x / $y;
if(($x <= $max_x)&&($y <= $max_y)){
 $new_x = $x;
}
 else if(($x_ratio * $y)<$max_y){
 $new_x = $max_x;
 $new_y = ceil($x_ratio * $y);
 }
 else{
 $new_x = ceil($y_ratio * $x);
 $new_y = $max_y;
 }
$src = imagecreatefromjpeg($img2);
$dst = imagecreate($new_x,$new_y);
imagecopyresized($dst,$src,0,0,0,0,$new_x,$new_y,$x,$y);
header("Content-type: image/jpeg");
imagejpeg($dst,"files/".$_FILES["img_resize"]["$img2"],-1);
imagedestroy($src);
imagedestroy($dst);

ผมลองรันดูมันก็คืนมาแบบนี้


Warning: imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable error: in c:\appserv\www\t-memorial\test_resize.php on line 52

Warning: imagecreatefromjpeg(): 'C:\WINDOWS.0\TEMP\php173.tmp' is not a valid JPEG file in c:\appserv\www\t-memorial\test_resize.php on line 52

Warning: imagecopyresized(): supplied argument is not a valid Image resource in c:\appserv\www\t-memorial\test_resize.php on line 54

Warning: imagedestroy(): supplied argument is not a valid Image resource in c:\appserv\www\t-memorial\test_resize.php on line 57
OK
Administrator
Fri 12 May 2006 10:21:26
not a valid JPEG
ตรวจสอบด้วยครับว่าเป็นไฟล์ JPEG หรือไม่ครับ
ถ้าเป็นไฟล์ GIF ก็เปลี่ยนไปใช้ imagecreatefromgif() และ imagegif() แทนครับ
merious
merious
Fri 12 May 2006 11:49:25

เฮ่ออออ นั่งทำทั้งคืน ไม่ได้ไร แถมแม่ยังมาค้นของผมเอาเงินไปอีก ><"  หงุดหงิดครับหงุดหงิด

ชั่งเหอะ อยากทราบว่า output Jpeg จากการ resize ข้างบน (ของที่ผมทำ) มันอยู่ตรงไหนหรอครับ

php-resize ดูจากรูปนะครับถ่ายจากหนังสือคัมภั PHP

merious
merious
Fri 12 May 2006 11:51:00
Out put รูปที่ได้การ resize แล้วมันอยู่ที่ตัวแปรไหนหรอครับ
merious
merious
Fri 12 May 2006 11:54:57
คือตอนนี้ผมทดสอบโดยสร้างฟอร์มขึ้นมา  1 ฟอร์ม โดยมี  multipart/form-data" แทรกรูปได้ เพียงอย่างเดียว แล้วส่งไปยัง test_resize.php และให้โค๊ดแปลรูปให้ resize และจัดการใส่ฐานข้อมูล โดยแยกเป็น img และ img_resize ผมก็ทำไมได้ซะที  ไม่รู้เป็นไร ไม่รู้ว่าตัวแปลไหนคือภาพ resize มาแล้ว ปวดหัวปวดหัว T__T ต้องบอกว่า ขอบคุนพี่มากๆที่ต้องมาคอยตอบผม คอยดูแลเอาใจใส่ผม ขอบคุณมากๆคับ
merious
merious
Fri 12 May 2006 11:57:09
Code ที่เขียนใน คห.14 $img2 หมายถึง ฟอร์มรูปภาพนะคับ img_resize หมายถึงฟิลด์ในตารางฐานข้อมูล
Administrator
Fri 12 May 2006 11:58:56
ดูที่ฟังก์ชั่นนี้ครับ
imagejpeg($desImg, "files/".$_FILES["userfile"]["name"], 80);

ที่ hilight ไว้เป็น path ที่ต้องการใช้บันทึกไฟล์ output ครับ ส่วนตัวเลข 80 คือ JPEG Loss Percentage ครับค่ายิ่งมากคุณภาพของภาพยิ่งดี ค่าน้อยไฟล์เล็กคุณภาพต่ำ

ฟังกชั่นทั้งหมดที่เขียนจะได้ไฟล์ที่ Resize แล้ว แต่ถ้าต้องการไฟล์ที่เป็นต้นฉบับก็สามารถเรียกได้จาก
$_FILES["userfile"]["tmp_name"] เนื่องจากการ Resize จะไม่มีการทำลายตัว temp file ครับ
merious
merious
Fri 12 May 2006 12:07:09

$_FILES["$img2"]["ไม่ได้เขียน"]

ผมทำแบบนี้อะคับ . . . . ผมผิดปล่าวอะ งง Userfile คือ $img2 ปล่าวครับ

merious
merious
Fri 12 May 2006 12:08:14

พอทำแบบนี้ค่าที่ได้ออกมามันก็ error เปง 'C:\WINDOWS.0\TEMP\php173.tmp'

merious
merious
Fri 12 May 2006 12:10:48

imagejpeg($desImg, "files/".$_FILES["$img2"]["$img2_name"], 80);

ส่วนนี่ผมทำแบบนี้

Administrator
Fri 12 May 2006 12:40:50
การเข้าถึงตัวแปร Array นั้นต้องอ้างผ่าน key ครับ เช่น
ถ้าใน form ของคุณมี <input type="file" name="img2">

เวลาเข้าถึง object จะได้เป็น $_FILES["img2"] คุณจะได้ object file resource โดยจะประกอบด้วย properties array อีกคือ
$_FILES["img2"]["name"] เป็นชื่อไฟล์
$_FILES["img2"]["tmp_name"] เป็นชื่อ temp file ที่อยู่ใน server
$_FILES["img2"]["type"] เป็นชนิดของไฟล์
$_FILES["img2"]["size"] เป็นขนาดไฟล์

ที่ผมใช้ imagejpeg($desImg, "files/".$_FILES["userfile"]["name"], 80); เพื่อให้ Save ลงใน directory files ในชื่อไฟล์ที่ upload เข้ามาครับ
merious
merious
Fri 12 May 2006 12:52:51

พี่คับ อิอิ ผมทำได้แล้วครับ ว้อยยยยยย ดีจัย มากมายเลย โอ้วววว T_T ซาบซึ้งนักนา ฮือๆๆๆๆๆ เย้เย้เย้ วู้วววววว พี่ครับ ผมขอบคุณพี่มากๆเลยนะ ส่วนเด๋วผมจะเอา code มาลงให้นะ เผื่อคนหลังๆจะได้ศึกษาต่อไปนะ ^_^

//เริ่มการ resize

$max_x = 97; //กำหนดความสูง
$max_y = 97; //กำหนดความกว้าง
$size = Getimagesize($myfile); //$myfile หมายถึงไฟล์รูปภาพที่ได้จากฟอร์ม
//เริ่มหาค่าขนาดของรูปภาพเพื่อนำไป resize
$x=$size[0]; // หาค่า ความสูง
$y=$size[1]; // หาค่าความกว้าง
$x_ratio=$max_x / $x;
$y_ratio=$max_x / $y;
if(($x <= $max_x)&&($y <= $max_y)){
 $new_x = $x;
}
 else if(($x_ratio * $y)<$max_y){
 $new_x = $max_x;
 $new_y = ceil($x_ratio * $y);
 }
 else{
 $new_x = ceil($y_ratio * $x);
 $new_y = $max_y;
 }
$src = imagecreatefromjpeg($myfile); //ทำการ copy รูปภาพจาก Source เก็บไว้เป็น image resource
$dst = imagecreatetruecolor($new_x,$new_y); //จากนั้นก็สร้าง Image Resource มารองรับรูปใหม่ที่ทำการ resize แล้ว
imagecopyresized($dst,$src,0,0,0,0,$new_x,$new_y,$x,$y);

//เริ่มทำการ buffer image stream ครับเพื่อนำลงฐานข้อมูลไม่ใช่ไฟล์ทั่วไป
ob_start();
imagejpeg($dst);
$binData = ob_get_contents();
ob_end_clean();

imagedestroy($src);
imagedestroy($dst);

//นำข้อมูลที่ resize แล้วลงฐานข้อมูล
mysql_connect($host,$user,$passwd);
$sql = "insert into yourfild (img_resize) values ('".addslashes($binData)."')";

mysql_db_query($dbname,$sql);

merious
merious
Fri 12 May 2006 12:54:10

ต้องกราบขอบพระคุณพี่เว็บมาสเตอร์อีกครั้งเป็นอย่างสูงงครับ (กราบบ , กราบบบบ!!)

merious
merious
Fri 12 May 2006 13:04:22

เอ้อ ขอแก้ไขเพื่อความสะดวกในการลงข้อมูลในฐานข้อมูลหน่อยนะจ๊ะ

//เริ่มทำการ buffer image stream ครับเพื่อนำลงฐานข้อมูลไม่ใช่ไฟล์ทั่วไป
ob_start();
imagejpeg($dst);
$binData = ob_get_contents();
ob_end_clean();

$img_resize = addslashes($binData);

$sql = "insert into yourfild (img_resize) values ('$img_resize')";

mysql_db_query($dbname,$sql);

จบงับ ^_^

aa
aa
Sun 13 Jan 2008 21:23:13

อันนี้เป็นตัวอย่างที่ผมใช้อยู่ เป็นการอัพโหลดรูปภาพ ได้หลาย ๆ ภาพนะครับ

$pic=$_FILES['pic']; // รับค่ารูปภาพมาทั้งหมด เก็บ เป็น array
$dir="../photo/$itemid/"; // ตั้งค่า directory
if(!empty($pic["tmp_name"][0])){
 if(!file_exists($dir)){
  mkdir($dir,0777);
 }
 for($i=0;$i<count($pic['name']);$i++){
   if(is_file($pic['tmp_name'][$i])){
 $images=$dir.$pic['name'][$i];
     /* $sqlUP="INSERT INTO picture (PItemID,PicName) VALUES ('$itemid','$picname')";
 ($result1=mysql_query($sqlUP)) or die ("Error up photo: ".mysql_error()."<br><br>Your SQL".$sqlUP);*/
copy($pic['tmp_name'][$i],$dir."/".$pic['name'][$i]);
$height = 400; //กำหนดขนาดความสูง
$size = getimagesize($images);
$width = round($height*$size[0]/$size[1]); //ขนาดความกว้่างคำนวนเพื่อความสมส่วนของรูป
if($size[2] == 1) {
$images_orig = imagecreatefromgif($images); //resize รูปประเภท GIF
} else if($size[2] == 2) {
$images_orig = imagecreatefromjpeg($images); //resize รูปประเภท JPEG
}
$photoX = imagesx($images_orig);
$photoY = imagesy($images_orig);
$images_fin = imagecreatetruecolor($width, $height);
imagecopyresampled($images_fin, $images_orig, 0, 0, 0, 0, $width+1, $height+1, $photoX, $photoY);
imagejpeg($images_fin, $dir."new.jpg"); //ชื่อไฟล์ใหม่ พร้อม directory
imagedestroy($images_orig);
imagedestroy($images_fin);

   }
 } 
}// จบการทำงานรูปภาพสินค้า ยังไงก็ลองเอาไปแก้นะครับ

Reply
Name:
E-mail:
Home | Services | Forum | Classified | Directories | Support | Contact
ATOM feed RSS 0.9 feed RSS 1.0 feed RSS 2.0 feed
Copyright © 2005 - 2007 Modoeye.com, All Rights Reserved.
Disclaimer | Privacy policy | Term of Use | Term of Services
Valid XHTML Valid CSS! PHP: Hypertext Preprocessor MySQL database Apache Powered! FreeBSD Power to serve
Modoeye Sitemap Client login