안녕하세요.
지난번에 말했듯이 재미난것을 가져와 봤습니다.
이름하여 Pixel to pixel 입니다.
대상 이미지를 픽셀 단위로 분리시킨 후 새로운 그림으로 재조합 합니다.
시간이 좀 오래 걸리겠지만, 추후에 픽셀 단위로 이미지를 제어하기 위한 첫걸음 입니다.
원리는 대상 이미지에서 가로 세로 이중 for loop을 돌면서 픽셀 하나를 추출하고, 새롭게 구성될 이미지의 해당 위치에 픽셀을 찍어줍니다. 이미지 크기가 크면 클 수록 처리할 것이 엄청나게 늘어납니다. 가령 100×100 픽셀이라면 10,000번이나 픽셀을 추출하고 새롭게 찍어야 하죠.
예제에 사용된 이미지는 영상처리 쪽에서 자주 사용되는 Lenna라는 모델의 사진입니다.
Playboy지에 올라온 사진을 한 연구원이 스캔하여 사용하면서 시작되었고, 지금까지 널리 쓰이고 있다는 후문입니다. 검색해보시면 관련 내용이 나올겁니다. 예제 이미지는 얼굴 뿐이지만, 전체 사진은 누드라는... '-'
동작은 메인페이지인 index.php와 이미지에서 픽셀 값을 뽑아내고 재구성하는 color.php로 구성됩니다. 따로 함수화하지는 않았습니다. color.php의 매개변수는 img와 mode가 있는데요. img는 대상 이미지의 주소를 나타내고, mode는 어떤 모드로 변환을 시키겠느냐를 정하도록 합니다. 지금은 단순히 픽셀에 아무런 변환을 하지 않으므로 기본 모드를 RGB로 지정했습니다. 추후에 컬러맵 추출이나 명암 추출등에서는 mode를 여러가지로 만들게 됩니다. color.php는 그대로 쓰고, mode의 매개변수만 달리하면 되지요.
주석은 달다가 말았는데, 어떤 원리인지 바로 아실 수 있을 겁니다.
index.php
<?
header("Content-type:text/html");
$img="lenna.png";
$img2="../lenna.png";
list($width, $height, $image_type) = getimagesize($img2);
switch ($image_type)
{
case 1: $im = imagecreatefromgif($img2); break;
case 2: $im = imagecreatefromjpeg($img2); break;
case 3: $im = imagecreatefrompng($img2); break;
default: trigger_error('Unsupported filetype!', E_USER_WARNING); break;
}
$color_tran=array();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Blur
</title>
<link rel="Shortcut Icon" href="favicon.ico" />
<style type="text/css">
div { font-size:10pt; font-family:돋움}
</style>
</head>
<body>
<div>
<div style="text-align:center"><h1>Blur</h1><h3>Blur v 0.1</h3>Image -> Blur image<br />Only GIF, JPG, PNG file <br /></div>
<br />
<div style="width:<?=$width*6?>px;height:<?=$height?>;margin:auto;">
<div style="width:<?=$width?>px;float:left;"><img src="../<?=$img?>" alt="" /></div>
<div style="width:<?=$width?>px;float:left;"><img src="../matrix.php?img=<?=$img?>&mode=BLUR" alt="" /></div>
<div style="width:<?=$width?>px;float:left;"><img src="../matrix.php?img=<?=$img?>&mode=BLUR2" alt="" /></div>
<div style="width:<?=$width?>px;float:left;"><img src="../matrix.php?img=<?=$img?>&mode=BLUR3" alt="" /></div>
<div style="width:<?=$width?>px;float:left;"><img src="../matrix.php?img=<?=$img?>&mode=BLUR4" alt="" /></div>
<div style="width:<?=$width?>px;float:left;"><img src="../matrix.php?img=<?=$img?>&mode=BLUR5" alt="" /></div>
<div style="width:<?=$width?>px;float:left;text-align:center;">Image</div>
<div style="width:<?=$width?>px;float:left;text-align:center;">Blur</div>
<div style="width:<?=$width?>px;float:left;text-align:center;">Blur2</div>
<div style="width:<?=$width?>px;float:left;text-align:center;">Blur3</div>
<div style="width:<?=$width?>px;float:left;text-align:center;">Blur4</div>
<div style="width:<?=$width?>px;float:left;text-align:center;">Blur5</div>
</div>
</div>
<div style="text-align:center;clear:both;">
<br /><br />
<a href="http://blog.kimchulho.com">http://blog.kimchulho.com</a>
</div>
<div style="text-align:center;clear:both;">
<p><br />
<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml11" alt="Valid XHTML 1.1" style="height:31;width:88;border:0;" /></a>
</p>
</div>
<div style="text-align:center;clear:both;">
<a href="http://s02.flagcounter.com/more/exm"><img src="http://s02.flagcounter.com/count/exm/bg=FFFFFF/txt=000000/border=CCCCCC/columns=2/maxflags=12/viewers=0/labels=0/" alt="free counters" /></a>
</div>
</body>
</html>
color.php
<?
$mode=!isset($_GET['mode'])? "RGB" : $_GET['mode'];
$per=!isset($_GET['per'])? "" : $_GET['per'];
$img=!isset($_GET['img'])? "lenna.png" : $_GET['img'];
list($width, $height, $image_type) = getimagesize($img);
switch ($image_type)
{
case 1: $im = imagecreatefromgif($img); break;
case 2: $im = imagecreatefromjpeg($img); break;
case 3: $im = imagecreatefrompng($img); break;
default: trigger_error('Unsupported filetype!', E_USER_WARNING); break;
}
$color_tran=array();
$gd = imagecreatetruecolor($width, $height);
for($i = 0; $i < $height ; $i++){
for($j = 0; $j < $width; $j++){
$start_x = $j;
$start_y = $i;
// 색상 인덱스 찾기
$color_index = imagecolorat($im, $start_x, $start_y);
// 인덱스에 해당하는 색 추출
$color_tran = imagecolorsforindex($im, $color_index);
// 현재 픽셀 색상을 RGB값으로 뽑기
$r=$color_tran['red'];
$g=$color_tran['green'];
$b=$color_tran['blue'];
// 적용될 색상값 초기화
$tr=0; $tg=0; $tb=0;
// RGB모드는 RGB값을 그대로
if($mode=='RGB'){
$tr=$r; $tg=$g; $tb=$b; }
$color_code = imagecolorallocate($gd, $tr, $tg, $tb);
imagesetpixel($gd, $start_x,$start_y, $color_code);
}
}
header('Content-Type: image/png');
imagepng($gd);
imagedestroy($gd);
?>


눈 부분을 확대해봤는데요. 동일합니다.
그런데, 어쩐지 용량은 원본이 더 크네요.
고 압축일 경우에는 원본 용량이 작겠지요.
png 원본 파일에 여러가지 정보가 들어있어서 그런가 봅니다.