티스토리 뷰

반응형

웹프로그램을 개발하는 과정에서 사진(이미지)파일을 선택해서 다중으로 입력하는 구문이 많이 어려웠습니다.

단일 파일은 만들어서 사용을 많이 했는데,

다중파일을 선택해서 이미지를 누르면 업로드 되고 화면에 나오는 것...

너무 많이 쓰는 방식인데,  php와 javascript를 사용해서 실제 구현한 내용을 정리해 봤습니다.

제품사진등록... 다중으로 선택가능하도록 만드는 구간.

<button type="button" id="delBtn"  class="btn btn-secondary"> DATA 삭제 </button>	&nbsp;		
<button type="button" id="regpicBtn"  class="btn btn-secondary" > 제품사진등록 </button>	&nbsp;		
<button  type="button" class="btn btn-secondary" id="EcountsendBtn"> Ecount 자료 전송화면 </button>	   	 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;

기본적으로 부트스트랩의 버튼을 사용해서 만들었지요.

제품사진등록 버튼을 구현하는 내용을 정리한 것입니다.

제이쿼리를 이용해서 창을 하나 띄웠습니다.

$("#regpicBtn").click(function(){    // 사진등록
  const num = $("#num").val();
  window.open('reg_pic.php?num=' + num ,"사진등록","width=1200, height=700, top=0,left=0,scrollbars=no");
});

 

이렇게 창을 하나 띄우게 만든 후  php에 javascript 구문을 함께 넣어서,

이미지파일의 압축부분의 로직이 들어있습니다.

원본그대로 올리면? 파일 크기가 엄청 큰거 다 아시죠? 그래서 압축하는 과정이 로직에 들어있습니다.

<meta charset="utf-8">
 
 <?php
 session_start(); 
  
 $num=$_REQUEST["num"]; 
 $parent=$num;
 
  if(isset($_REQUEST["check"])) 
	 $check=$_REQUEST["check"]; 
   else
     $check=$_POST["check"]; 
 
 require_once("../lib/mydb.php");
 $pdo = db_connect();
 
 try{
     $sql = "select * from mirae8440.(DB테이블명) where num=?";
     $stmh = $pdo->prepare($sql);  
     $stmh->bindValue(1, $num, PDO::PARAM_STR);      
     $stmh->execute();            
      
     $row = $stmh->fetch(PDO::FETCH_ASSOC); 	 
  
     $PROD_DES = $row["PROD_DES"];
					
     }catch (PDOException $Exception) {
       print "오류: ".$Exception->getMessage();
     }  	 

if(isset($_POST['submit'])){
    $countfiles = count($_FILES['file']['name']);
    for($i=0;$i<$countfiles;$i++){
        $filename = $_FILES['file']['name'][$i];
        $sql = "INSERT INTO fileup(id,name) VALUES ('$filename','$filename')";
        $db->query($sql);
        move_uploaded_file($_FILES['file']['tmp_name'][$i],'imgwork/'.$filename);
    }
}
?>

 <!DOCTYPE HTML>
 <html>
 <head> 
 <meta charset="utf-8">
 <head>
 <meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link rel="stylesheet" href="../css/partner.css" type="text/css" />

<style>

.progress {
  margin: 10px;
  width: 700px;
}

.blink {
	-webkit-animation: blink 1.05s linear infinite;
	-moz-animation: blink 1.05s linear infinite;
	-ms-animation: blink 1.05s linear infinite;
	-o-animation: blink 1.05s linear infinite;
	 animation: blink 1.05s linear infinite;
}
@-webkit-keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 1; }
	50.01% { opacity: 0; }
	100% { opacity: 0; }
}
@-moz-keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 1; }
	50.01% { opacity: 0; }
	100% { opacity: 0; }
}
@-ms-keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 1; }
	50.01% { opacity: 0; }
	100% { opacity: 0; }
}
@-o-keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 1; }
	50.01% { opacity: 0; }
	100% { opacity: 0; }
}
@keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 1; }
	50.01% { opacity: 0; }
	100% { opacity: 0; }
}
</style>

 <title> 사진등록/수정 </title>
 </head>
  <body>
<div id="top-menu">

</div>
</div>
<br> 
			<div class="row">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
			<h1 class="display-1  text-left">
  <input type="button" class="btn btn-secondary btn-lg " value="닫기" onclick="self.close();"> </h1> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  </div>
<br>
<br>
<form id="board_form" name="board_form" method="post" action="pic_insert.php"   enctype="multipart/form-data">  
     
	 <input type="hidden" id=childnum name=childnum value="<?=$childnum?>" >
	 <input type="hidden" id=check name=check value="<?=$check?>" >
	 <input type="hidden" id=parent name=parent value="<?=$parent?>" >
	 <input type="hidden" id=num name=num value="<?=$num?>" >
	 <input type="hidden" id=mode name=mode value="<?=$mode?>" >
	 <input type="hidden" id=PROD_DES name=PROD_DES value="<?=$PROD_DES?>" >
	 <div  class="container">
			<div class="row">

	 <H1  class="display-5 font-center text-center" > 사진 등록/수정 </H1> 
 </div>
 
 			<div class="row">				
			   <div id=progressbar class="blink" style="display:none;">
			 <!--  <div id=progressbar style="display:none;" class=blinking > -->
			   <div class="row">				 </div> <br>
					<h1 class="display-1  text-left"> 사진등록을 서버에 저장중입니다. <br> (잠시만 기다려주세요.) </h1>
					<div class="progress">
					  <div id="dynamic" class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
						<span id="current-progress"></span>
					  </div>
				   	</div>			
								<div class="row">				 </div> <br>
				</div>
			</div>
			
			<br>
			<div class="row">
		     <h1 class="display-5 font-center text-left"> 		   
					품명(규격) :   <?=$PROD_DES?> 	   
			<br> 
			<br> 
		<?php 
			if($filename1!=null) {
			  print "기존 업로드 파일 있음 " . $filename1 ;  
			  echo "<img src='". $imgurl1  . "'";
			  			  print " </div> <br> <br>";
			  }
			?>
		  <div class="row">
		  <input id="upfile"  name="upfile[]" class="input" type="file" onchange="this.value" multiple >
		  
	   </div>	    	

 			<div class="row">				
			   <div id=progressbar1 class="blink" style="display:none;">
			 <!--  <div id=progressbar style="display:none;" class=blinking > -->
			   <div class="row">				 </div> <br>
					<h1 class="display-1  text-left"> 사진등록을 서버에 저장중입니다. <br> (잠시만 기다려주세요.) </h1>
					<div class="progress">
					  <div id="dynamic" class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
						<span id="current-progress"></span>
					  </div>
				   	</div>			
					
								<div class="row">				 </div> <br>
				</div>
			</div>   	   
	   	   							
		<div class="row">

		         <h1 class="display-5 font-center text-left"> 		   
       
						<br>
  
			<div class="row">							
			<h1 class="display-1  text-left">
  <input type="button" class="btn btn-primary btn-lg " value="서버에 저장하기" onclick="javascript:pro_submit()" > </h1>

	   </div>	    		
   
	   </div> 

 </div> 
 </form>
	 
 </body>
</html>    

<script> 

/* function new(){
 window.open("viewimg.php","첨부이미지 보기", "width=300, height=200, left=30, top=30, scrollbars=no,titlebar=no,status=no,resizable=no,fullscreen=no");
} */
var imgObj = new Image();
function showImgWin(imgName) {
imgObj.src = imgName;
setTimeout("createImgWin(imgObj)", 100);
}
function createImgWin(imgObj) {
if (! imgObj.complete) {
setTimeout("createImgWin(imgObj)", 100);
return;
}
imageWin = window.open("", "imageWin",
"width=" + imgObj.width + ",height=" + imgObj.height);
}

   function inputNumberFormat(obj) { 
    obj.value = comma(uncomma(obj.value)); 
} 
function comma(str) { 
    str = String(str); 
    return str.replace(/(\d)(?=(?:\d{3})+(?!\d))/g, '$1,'); 
} 
function uncomma(str) { 
    str = String(str); 
    return str.replace(/[^\d]+/g, ''); 
}

function input_Text(){
    document.getElementById("test").value = comma(Math.floor(uncomma(document.getElementById("test").value)*1.1));   // 콤마를 계산해 주고 다시 붙여주고
}  

function copy_below(){	   
}  

function pro_submit()
     {
		 
           $('#progressbar').show();	
           $('#progressbar1').show();	
           $('#progressbar2').show();	
           $('#board_form').submit();	

     }

</script>

 

서버저장하기 버튼을 누르면 동작하는 것은 pic_insert.php 내용입니다. 서버에 저장하는 내용의 구현입니다.

 <?php session_start();  

 if(isset($_REQUEST["num"]))
    $num=$_REQUEST["num"];
		 else 
			$num="";			
 
  if(isset($_REQUEST["check"])) 
	 $check=$_REQUEST["check"]; 
   else
     $check=$_POST["check"]; 			


$countfiles = count($_FILES['upfile']['name']);
for($i=0;$i<$countfiles;$i++){
	$filename = $_FILES['upfile']['name'][$i];
//	$target_file = 'imgwork/'.$filename;
//	move_uploaded_file($_FILES['file']['tmp_name'][$i],$target_file);
//	$statement->execute(array($filename,$target_file));
print $filename;
if($filename !='') {   			
	//Auth key
	define('UPLOAD_ERR_INI_SIZE',"100000000");

    $uploads_dir = './imgwork'; //업로드 폴더 -현재 처리하는 폴더 하부로 imgtest 폴더
    $allowed_ext = array('jpg','jpeg','png','gif','JPG','JPEG','PNG','GIF'); //이미지 파일만 허용
 
 
 	//첨부파일이 있다면
	$uploadSize = 100000000;
	@mkdir("$upload_dir", 0707);
  	@chmod("$upload_dir", 0707);
	
  	// 올라간 파일의 퍼미션을 변경합니다.
  	chmod("$uploads_dir", 0755);

    // 변수 정리
    $error = $_FILES['upfile']['name'][$i];
    $name = $_FILES['upfile']['name'][$i];     
    $tmpNm =  explode( '.', $name );
    $ext = strtolower(end($tmpNm));

     echo "$ext <br>";
    // 확장자 확인
    if( !in_array($ext, $allowed_ext) ) {
        echo "허용되지 않는 확장자입니다.";
        exit;
    }
	
	
   // $newfile=$tmpNm[0].".".$ext ;
	$new_file_name = date("Y_m_d_H_i_s");
	$newfilename1 = $new_file_name."_" . $i . "." . $ext;      
    $url1 = $uploads_dir.'/'.$newfilename1; //올린 파일 명 그대로 복사해라.  시간초 등으로 파일이름 만들기
	
	// 사진회전시키기
	    
     $tmpimage = imagecreatefromjpeg($url1);
	 $exif = exif_read_data($url1);
	 
	 print '사진 정보' . $exif['Orientation'] . "<br>";
	 
			if(!empty($exif['Orientation']))
				{
					switch($exif['Orientation'])
					{
						case 8:
							$url1 = imagerotate($url1,90,0);
							break;
						case 3:
							$url1 = imagerotate($url1,180,0);
							break;
						case 6:
							$url1 = imagerotate($url1,-90,0);
							break;

					}
				}


	//요기부분 수정했습니다.
	$filename1 = compress_image($_FILES['upfile']["tmp_name"][$i], $url1, 70); //실제 파일용량 줄이는 부분

	list($width, $height, $type, $attr) = getImagesize($_FILES['upfile']["tmp_name"][$i]);
	echo $width."<br>";
	echo $height."<br>";
	echo $type."<br>";
	echo $attr."<br>";

	if($width > 700){
	 $switch_s=80;
	}else{
	 $switch_s=100;
	}
    $buffer = file_get_contents($url1);
 
    // 파일 정보 출력
    echo "<h2>파일 정보</h2> <h1>
        <ul>
            <li>자료번호: $num</li>
            <li>파일명: $name</li>
            <li>확장자: $ext</li>
            <li>url: {$url1}</li>
            <li>filename: {$filename1}</li>
        </ul> </h1>";
    
	$re_image = new Image($filename1);
	$rate=$width/$height;
	if($width>$height) {
			$re_image -> width(800);
			$re_image -> height(800/$rate);
		}
        else
		{
			$re_image -> width(800*$rate);
			$re_image -> height(800);
		}
		$re_image -> save();

		 require_once("../lib/mydb.php");
		 $pdo = db_connect();
     // insert
		try{		 
			$pdo->beginTransaction();   
			$sql = "insert into mirae8440.espicfile ";
			$sql .=" (parentnum, picname) " ;        
			$sql .=" values(?, ?) " ;        
			   
			 $stmh = $pdo->prepare($sql); 

			 $stmh->bindValue(1, $num, PDO::PARAM_STR);             
			 $stmh->bindValue(2, $newfilename1, PDO::PARAM_STR);   
			 
			 $stmh->execute();
			 $pdo->commit(); 
				} catch (PDOException $Exception) {
				   $pdo->rollBack();
				   print "오류: ".$Exception->getMessage();
			 }  	
    // // update
			 // try{		 
			// $pdo->beginTransaction();   
			// $sql = "update mirae8440.espicfile set ";
			// $sql .=" parentnum=?, picname=?, copiedfile where num=? LIMIT 1" ;        
			   
			 // $stmh = $pdo->prepare($sql); 

			 // $stmh->bindValue(1, $newfilename1, PDO::PARAM_STR);             
			 // $stmh->bindValue(2, $num, PDO::PARAM_STR);             
			 
			 // $stmh->execute();
			 // $pdo->commit(); 
				// } catch (PDOException $Exception) {
				   // $pdo->rollBack();
				   // print "오류: ".$Exception->getMessage();
			 // }      
    }
} // end of for statement    
 
 
class Image {    
    var $file;
    var $image_width;
    var $image_height;
    var $width;
    var $height;
    var $ext;
    var $types = array('','gif','jpeg','png','swf');
    var $quality = 70;
    var $top = 0;
    var $left = 0;
    var $crop = false;
    var $type;
    
    function __construct($name='') {
        $this->file = $name;
        $info = getimagesize($name);
        $this->image_width = $info[0];
        $this->image_height = $info[1];
        $this->type = $this->types[$info[2]];
        $info = pathinfo($name);
        $this->dir = $info['dirname'];
        $this->name = str_replace('.'.$info['extension'], '', $info['basename']);
        $this->ext = $info['extension'];
    }
    
    function dir($dir='') {
        if(!$dir) return $this->dir;
        $this->dir = $dir;
    }
    
    function name($name='') {
        if(!$name) return $this->name;
        $this->name = $name;
    }
    
    function width($width='') {
        $this->width = $width;
    }
    
    function height($height='') {
        $this->height = $height;
    }
    
    function resize($percentage=50) {
        if($this->crop) {
            $this->crop = false;
            $this->width = round($this->width*($percentage/100));
            $this->height = round($this->height*($percentage/100));
            $this->image_width = round($this->width/($percentage/100));
            $this->image_height = round($this->height/($percentage/100));
        } else {
            $this->width = round($this->image_width*($percentage/100));
            $this->height = round($this->image_height*($percentage/100));
        }
        
    }
    
    function crop($top=0, $left=0) {
        $this->crop = true;
        $this->top = $top;
        $this->left = $left;
    }
    
    function quality($quality=70) {
        $this->quality = $quality;
    }
    
    function show() {
        $this->save(true);
    }
    
    function save($show=false) {
 
        if($show) @header('Content-Type: image/'.$this->type);
        
        if(!$this->width && !$this->height) {
            $this->width = $this->image_width;
            $this->height = $this->image_height;
        } elseif (is_numeric($this->width) && empty($this->height)) {
            $this->height = round($this->width/($this->image_width/$this->image_height));
        } elseif (is_numeric($this->height) && empty($this->width)) {
            $this->width = round($this->height/($this->image_height/$this->image_width));
        } else {
            if($this->width<=$this->height) {
                $height = round($this->width/($this->image_width/$this->image_height));
                if($height!=$this->height) {
                    $percentage = ($this->image_height*100)/$height;
                    $this->image_height = round($this->height*($percentage/100));
                }
            } else {
                $width = round($this->height/($this->image_height/$this->image_width));
                if($width!=$this->width) {
                    $percentage = ($this->image_width*100)/$width;
                    $this->image_width = round($this->width*($percentage/100));
                }
            }
        }
        
        if($this->crop) {
            $this->image_width = $this->width;
            $this->image_height = $this->height;
        }
 
        if($this->type=='jpeg') $image = imagecreatefromjpeg($this->file);
        if($this->type=='png') $image = imagecreatefrompng($this->file);
        if($this->type=='gif') $image = imagecreatefromgif($this->file);
        
        $new_image = imagecreatetruecolor($this->width, $this->height);
        imagecopyresampled($new_image, $image, 0, 0, $this->top, $this->left, $this->width, $this->height, $this->image_width, $this->image_height);
        
        $name = $show ? null: $this->dir.DIRECTORY_SEPARATOR.$this->name.'.'.$this->ext;
    
        if($this->type=='jpeg') imagejpeg($new_image, $name, $this->quality);
        if($this->type=='png') imagepng($new_image, $name);
        if($this->type=='gif') imagegif($new_image, $name);
 
        imagedestroy($image); 
        imagedestroy($new_image);
        
    }
    
}			 

// 파일 압축 메소드 
    function compress_image($source, $destination, $quality) { 
        $info = getimagesize($source); 
        if ($info['mime'] == 'image/jpeg') 
            $image = imagecreatefromjpeg($source); 
        elseif ($info['mime'] == 'image/gif') 
            $image = imagecreatefromgif($source); 
        elseif ($info['mime'] == 'image/png') 
            $image = imagecreatefrompng($source); 

     elseif ($info['mime'] == 'image/x-ms-bmp') 
      $image = imagecreatefrombmp($source);

        imagejpeg($image, $destination, $quality); 
        return $destination;
    }

echo "<script> opener.document.getElementById('pInput').value='100'; </script>";   // 부모창에 100 기록해보기
echo "<script> self.close(); </script>";   // 창닫기

// header("Location:http://8440.co.kr/es/reg_pic.php?num=$num&check=$check");

?>

 

정리하면... 사진파일을 멀티로 올리는 것은 간단한 소스가 아닙니다. 처리하는 것이 복잡해서 나름 연구했는데도...

구현을 성공해서 사용하고 있지만, 할때마다 구현이 쉽지 않다는 것을 많이 느끼고 있습니다.

 

좀더 소스를 가다듬으면 업데이트되고 좀더 요약된 내용으로 만들고 싶네요.

좀더  코드를 줄이고 간명하게 코드를 정리하고 있으니, 완성되면 또 올려보고 싶습니다.

파일업로드... 너무 많이 사용하고 너무 중요한 것이니...

여러번 반복해서 습득해야 할 것 같아요~

코딩하는 모든 분들..

파일 업로드 구현에 성공하시길 기원합니다.

반응형
댓글