php 이미지 사이즈 줄인 후 업로드



php 이미지 사이즈 줄인 후 업로드 하는 방법을 알아보겠습니다. 
크기가 큰 이미지 파일이 넘어오는 경우에는 용량을 줄여야 서버에 보관하기도 쉽고, 
다른 파일에서 열어볼 때도 시간 지연 없이 열어 볼 수 있기 때문에 줄이는 경우가 많습니다. 

php 는 이미지를 업로드 할 때, 임시 파일에 들어있다가 업로드를 하는 방식을 사용합니다.
이미지를 업로드 할 때 임시 파일에 있는 파일을 바로 사이즈를 줄여서 업로드 하는 방법과 
이미지를 일단 업로드 하고, 그 폴더에 있는 파일을 사이즈를 줄이는 경우가 있습니다. 


>> form 형식  

아래와 같은 형식이고 아래에서 img, button 은 필요 없습니다.
선택한 이미지를 바로 보여줄 때 사용된 구조입니다. 
그리고 주석처리 되어 있는 부분은 php 로 파일을 올릴 수 있는 최대 용량의 제한을 보여주는 form 입니다. 

그것도 모르고 이 것 때문에 삽질을 많이 했네요. 

1
2
3
4
5
6
7
<form enctype="multipart/form-data" action="imageUpload.php" method="POST">
   
  <img id="mainImg" style="max-width:500px; display: block;" />
  <button class="replace">사진 올리기button>
  <input name="mainImgInput" class="input" type="file" id="mainImgInput" />
  <input type="submit" value="upload" />
cs

필요한 것만 추리면, 위는 아래와 같은 소스 코드로 줄일 수 있습니다. 

1
2
3
4
<form enctype="multipart/form-data" action="imageUpload.php" method="POST">
  <input name="mainImgInput" class="input" type="file" id="mainImgInput" />
  <input type="submit" value="upload" />
cs


>> php 코드 ( 일단 업로드 하고, 업로드 된 파일을 resize 하기 ) 

<?
// 설정
$uploads_dir = 'userImages/test';
$allowed_ext = array('jpg','jpeg','png','gif');
// 폴더 존재 여부 확인 ( 없으면 생성 )
if ( !is_dir ( $uploads_dir ) ){
mkdir( $uploads_dir );
}
// 변수 정리
$error = $_FILES['mainImgInput']['error'];
$name = $_FILES['mainImgInput']['name'];
$ext = array_pop(explode('.', $name));
// 오류 확인
if( $error != UPLOAD_ERR_OK ) {
switch( $error ) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
echo "파일이 너무 큽니다. ($error)";
break;
case UPLOAD_ERR_NO_FILE:
echo "파일이 첨부되지 않았습니다. ($error)";
break;
default:
echo "파일이 제대로 업로드되지 않았습니다. ($error)";
}
exit;
}
// 확장자 확인
if( !in_array($ext, $allowed_ext) ) {
echo "허용되지 않는 확장자입니다.";
exit;
}
// 파일 업로드
move_uploaded_file( $_FILES['mainImgInput']['tmp_name'], "$uploads_dir/$name");
// 파일 정보 출력
echo "
<h2>파일 정보</h2>
<p>파일명: $name</p>
<p>확장자: $ext</p>
<p>파일형식: {$_FILES['mainImgInput']['type']}</p>
<p>파일크기: {$_FILES['mainImgInput']['size']} 바이트</p>
";
// 파일 압축 메소드
function compress($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);
imagejpeg($image, $destination, $quality);
return $destination;
}
// 파일 리사이즈 후 복사하기
$source_img = $_FILES['mainImgInput']['tmp_name'];
$destination_img = $_FILES['mainImgInput']['tmp_name'];
$d = compress($source_img, $destination_img, 90);
?>


출처 된 소스에서 디렉터리의 존재 여부를 체크해서 없으면 만드는 부분을 7줄에서 만들고 있습니다. 

compress 라는 함수는 인자로 ( 원래 경로 , 생성할 경로 , 퀄리티 ) 의 형식을 가지고 있다. 

퀄리티를 90 으로 했을 때는, 원래 사이즈가 440kb 인 경우 110kb 
퀄리티를 50 으로 했을 때는, 원래 사이즈가 440kb 인 경우 44.0kb 정도로 줄여졌다. 



>> php 코드 ( 임시 파일에 있는 파일을 바로 업로드 하기 ) 

<?
// 설정
$uploads_dir = 'userImages/test';
$allowed_ext = array('jpg','jpeg','png','gif');
// 폴더 존재 여부 확인 ( 없으면 생성 )
if ( !is_dir ( $uploads_dir ) ){
mkdir( $uploads_dir );
}
// 변수 정리
$error = $_FILES['mainImgInput']['error'];
$name = $_FILES['mainImgInput']['name'];
$ext = array_pop(explode('.', $name));
// 오류 확인
if( $error != UPLOAD_ERR_OK ) {
switch( $error ) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
echo "파일이 너무 큽니다. ($error)";
break;
case UPLOAD_ERR_NO_FILE:
echo "파일이 첨부되지 않았습니다. ($error)";
break;
default:
echo "파일이 제대로 업로드되지 않았습니다. ($error)";
}
exit;
}
// 확장자 확인
if( !in_array($ext, $allowed_ext) ) {
echo "허용되지 않는 확장자입니다.";
exit;
}
$url = 'userImages/test/destination.jpg';
$filename = compress_image($_FILES["mainImgInput"]["tmp_name"], $url, 80);
$buffer = file_get_contents($url);
// 파일 정보 출력
echo "파일 정보
파일명: $name
확장자: $ext
파일형식: {$_FILES['mainImgInput']['type']}
파일크기: {$_FILES['mainImgInput']['size']} 바이트
url: {$url}
filename: {$filename}
";
// 파일 압축 메소드
function compress($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);
imagejpeg($image, $destination, $quality);
return $destination;
}
?>


나머지는 거의 다 동일하고 38~40 줄을 유의해서 보자. ( 40 줄은 안 써주어도 된다. 핵심은 39 줄 ) 
원래 경로에 버퍼를 넣어주고, 원하는 파일의 이름을 써주면 ?? 파일이 생성된다. 


>> 결과 


결과는 위와 같이 나오게 된다. 



실제 폴더에는 이렇게 저장된다. 



80 의 압축률로 압축을 했을 경우 위와 같은 용량 차이가 남을 알 수 있다. 




!! 팁 !!
temp 파일에 있는 경우에는 한 번 사용하면 그 다음에는 파일이 사라져서 사용할 수 없다.
ex ) 업로드 하고 나서, 임시 파일에 있는 파일을 사용하려고 하면 사용할 수 없다. 

- 출처 -