'imagemagick'에 해당되는 글 2건

  1. 2009.06.11 PEAR 활용 imagick 설치 및 PHP 캐싱 (1)
  2. 2009.05.15 ImageMagick을 이용한 썸네일(thumbnail) 만들기
2009. 6. 11. 10:04

PEAR 활용 imagick 설치 및 PHP 캐싱

http://pecl.php.net/package/imagick

이 사이트에 방문하시어 최종 업데이트 된 제품을 다운로드 합니다. 

wget http://pecl.php.net/get/imagick-2.2.1.tgz

# tar zxf imagick-2.2.1.tgz
# cd imagick-2.2.1.tgz

# phpize

# ./configure  --with-php-config=/usr/local/php/bin/php-config

 에러가 발생할 수 있습니다. 

checking ImageMagick MagickWand API configuration program... configure: error: not found. Please provide a path to MagickWand-config or Wand-config program.

# yum -y install ImageMagick-devel

Transaction Check Error:
  file /etc/fonts/conf.d/30-aliases-fedora.conf from install of fontconfig-2.4.1-7.el5 conflicts with file from package fontconfig-2.4.1-6.el5
  file /usr/share/hal/fdi/information/10freedesktop/20-video-quirk-pm-el5-lenovo.fdi from install of hal-0.5.8.1-35.el5 conflicts with file from package hal-0.5.8.1-25.el5
  file /usr/share/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi from install of hal-0.5.8.1-35.el5 conflicts with file from package hal-0.5.8.1-25.el5

사실 전에 설치할 때는 이런 에러가 없었는데, 에러가 나서 다음 두 가지 프로그램을 더 설치하도록 하겠습니다.

# yum -y install fontconfig

# yum -y install hal

그리고 다시 한번 반복해줍니다.

# yum -y install ImageMagick-devel

# make
# make install

Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/

이렇게 해주면 정상적으로 처리가 됩니다.

 

그런 다음 확장자를 php.ini에 등록시켜 줘야 합니다.
다음 사항을 수정시켜줍니다. 또는 추가해줍니다.  

; Directory in which the loadable extensions (modules) reside.
;extension_dir = "./"
extension_dir = "/usr/local/php/lib/php/extensions"
enable_dl = On
extension="no-debug-non-zts-20060613/imagick.so" 

아파치 재시작해줘야 합니다.

그리고 한가지 더 phpinfo를 보게 되면 다음과 같은 옵션이 보여야 합니다.

 



PEAR로 PHP 프로그램 캐싱하기


캐싱(caching)은
PHP 세계에서 현재 가장 빈번하게 언급되는 주제이다. PHP는 동적 웹 페이지를 생성하므로 웹 페이지가 요청 되어지면 매번 스크립트가 실행되어야 하며 실행 결과가 같다고 하더라도 그 결과는 매번 연산되어야 한다. 게다가 PHP는 스크립트가 요청될 때마다 컴파일한다. 이러한 오버헤드는 과중한 트래픽과 함께 사이트의 속도를 느리게 만들기도 한다. 다행히도 웹 요청 결과는 저장되거나 캐시될 수 있으며 스크립트를 재실행 하거나 컴파일 할 필요 없이 매칭 요청으로 제시될 수 있다. ZendCache같은 상품이나 Alternate PHP Cache같은 오픈 소스 솔루션은 바이트 코드인 PHP 스크립트의 컴파일된 버전을 캐시해준다. 'PHP land' 솔루션이 PHP디자인에 타격을 가하는 동안 'Userland'솔루션은 웹 애플리케이션 디자인과 프로그램에서 발생하는 일반적인 병목현상을 해결함으로써 한 단계 더 발전할 수 있다.(여기 사용된 'PHP land'는 PHP 4를 구동시키는 Zend Engine과 같은 PHP 언어 수준을 말하며 'Userland'는 PHP사용자에 의해 저작된 것을 말한다.) 데이터베이스 안에 저장된 거대한 카탈로그와 같은 상업적 응용 프로그램을 생각해 보자. 현실적으로 그 카탈로그의 정보는 하루 한 두 번 특정 시간대에 바뀔 것이다. 그리고 여전히 제품 페이지에 요청이 들어올 때마다 데이터베이스 쿼리는 수행된다. 이러한 오버로드는 쿼리 결과나 요청 페이지의 완벽한 HTML 출력을 캐싱함으로써 피할 수 있다. PEAR의 캐시 패키지는 동적인 내용, 데이터베이스 쿼리와 PHP 함수 호출을 캐싱하기 위한 프레임워크를 제공한다. 어디에서 PEAR 캐시를 얻을 수 있는가? 펄이 CPAN, TeX가 CTAN을 가지고 있듯이 PHP또한 클래스와 라이브러리 모듈을 위한 중앙 저장소를 가지고 있다. 이 중앙 저장소를 PEAR라고 부르며 이는 PHP Extension and Add-On Repository의 약자이다. 이 기사는 여러분이 PEAR 환경 설정을 이미 마쳤다는 가정 하에 기술된 것이다. 보기로 든 예제는 CVS에서 사용하는 PEAR Cache 개발 버전으로 만들어지고 테스트한 것이다. PEAR 캐시는 어떻게 작동하는가? PEAR 캐시 패키지는 일반 Cache 클래스, 함수 호출을 캐시하기위한 클래스, 스크립트 출력과 같은 몇 개의 특화된 하위 클래스로 구성된다. Cache 클래스는 실질적으로 캐시된 데이터를 저장하고 운영하는 Container 클래스라 불리는 다양한 종류의 클래스를 이용할 수 있다. 다음은 개개의 매개변수와 함께 PEAR 캐시의 현재 컨테이너 구현 목록을 정리해 놓은 것이다.

  • file - file 컨테이너는 캐시된 데이터를 파일 시스템 내에 저장한다. 이것은 가장 빠른 컨테이너이다.
  • Cache_dir - 이것은 컨테이너가 파일을 저장하는 디렉토리이다.
  • Filename_prefix - 캐시 파일을 위한 파일명 접두사, 예를 들어 "cache_"
  • shm - shm 컨테이너는 공유 메모리 내로 캐시된 데이터를 저장한다. 벤치마크는 이 컨테이너의 현재 구현이 file 컨테이너보다 훨씬 느리다는 것을 암시한다.
  • shm_key - 사용되는 공유 메모리 키
  • shm_perm - 공유 메모리 조각을 위한 퍼미션
  • shm_size - 할당된 공유 메모리의 크기
  • sem_key - 사용되는 새마포어 키
  • sem_perm - 세마포어를 위한 퍼미션
  • db - PEAR의 데이터베이스 분리 계층
  • dsn - DSN 사용된 데이터베이스 연결의 DSN. 세부 사항을 위해 PEAR DB 서류라고 명기해야 함.
  • Cache_table - 사용되는 테이블의 이름
  • phplib - phplib 컨테이너는 캐시된 데이터를 저장하기 위한 데이터베이스 분리 계층을 사용한다.
  • db_class
  • db_file
  • db_path
  • local_file
  • local_path
  • ext/dbx - PHP 데이터베이스 분리 계층 확장자. 이것은 여러분이 캐시된 데이터를 데이터베이스 내로 저장하고자 할 때 일반적으로 선택하는 컨테이너이다.
  • module
  • host
  • db
  • username
  • password
  • cache_table
  • persistent
PEAR 캐시를 사용함으로써 얻을 수 있는 수행상 이점은 여러분이 어떤 캐시 컨테이너를 사용하느냐에 크게 좌우된다. 예를 들어, 데이터베이스의 쿼리 결과를 다시 데이터베이스로 저장시키는 것은 아무 의미가 없다는 뜻이다. 함수 호출 캐싱 PEAR Cache의 Function Cache 모듈은 어떤 함수나 메소드의 결과와 출력이 내장 PHP함수나 사용자 정의 함수라 하더라도 캐시한다. 초기 설정값은 File 컨테이너를 사용하고 캐시 데이터를 function_cache 라 이름 붙여진 디렉토리로 갖다 놓는다. Cache_Function 클래스 생성자는 선택 가능한 모든 매개변수를 3개까지 받아들일 수 있다.
  • $container 사용할 캐시 컨테이너의 이름
  • $container_options 캐시 컨테이너를 위한 매개변수의 배열
  • $expires 캐시 개체가 만기된 후 시간을 나타내는 숫자

Cache_Function 클래스의 call()메소드를 사용하는 일반 함수 호출을 래핑함으로써 캐시된 함수 호출은 유발된다. Call()을 사용하는 것은 매우 쉽다. 첫번째 매개변수는 호출할 함수나 메소드의 이름을 지정하고 호출된 함수나 메소드의 매개변수가 그 뒤에 제시된다. Call()의 두 번째 매개변수는 호출된 함수나 메소드의 첫번째 매개변수이다. 이와 같은 방법으로 프로그램은 계속 작성된다. 그러면 이제 예제를 한 번 살펴보자.

 

예제 1: 캐싱 함수와 메소드 호출

<.;?php // Load PEAR Cache's Function Cache < 'Cache/Function.php'; // Define some classes and functions / methods // for demonstration class foo { function bar($test) { echo "foo::bar($test)<br>"; } } class bar { function foobar($object) { echo '$'.$object.'->foobar('.$object.')<br>'; } } $bar = new bar; function foobar() { echo 'foobar()'; } // Get Cache_Function object $cache = new Cache_Function(); // Cached call to static method bar() of class foo // (foo::bar()) $cache->call('foo::bar', 'test'); // Cached call to method foobar() of object bar // ($bar->foobar()) $cache->call('bar->foobar', 'bar'); // Cached call to function foobar() $cache->call('foobar'); ?>

함수 호출의 캐싱은 일일 기준으로 변하는 XML 소스의 XSL 변형과 같이 시간을 많이 소비하는 상황에서 편리하게 사용된다. 출력 캐싱 상업 응용 프로그램의 도입 예제를 돌이켜 볼 때, 이제 여러분은 요구할 때마다 데이터베이스에서 꺼내 사용할 수 있는 카탈로그 정보나 파싱된 템플릿 요소를 캐시할 수 있다. 우리는 이제 Cache_Output 클래스와 함께 스크립트의 완벽한 출력을 캐시함으로서 한 단계 더 발전하는 것이다.

 

예제 2: 캐싱 스크립트의 출력

<?php // Load PEAR Cache's Output Cache require_once 'Cache/Output.php'; $cache = new Cache_Output('file', array('cache_dir' => '.') ); // Compute unique cache identifier for the page we're about // to cache. We'll assume that the page's output depends on // the URL, HTTP GET and POST variables and cookies. $cache_id = $cache->generateID(array('url' => $REQUEST_URI, 'post' => $HTTP_POST_VARS, 'cookies' => $HTTP_COOKIE_VARS) ); // Query the cache if ($content = $cache->start($cache_id)) { // Cache Hit echo $content; die(); } // Cache Miss // -- content producing code here -- // Store page into cache echo $cache->end(); ?>
Cache_Output 클래스를 사용하면 쉽게 동적 데이터베이스 구동 웹 애플리케이션을 정적 애플리케이션으로 변화시킬 수 있다. 이것은 사이트의 수행 능력을 현저하게 개선시킬 수 있다. 점점 더 많은 웹 사이트가 HTML 컨텐트를 위해 GZIP를 사용한다. 이것은 서버의 대역폭을 감소시키며 트래픽 발생으로 인한 비용도 줄여준다. 게다가, 그것은 이러한 모뎀 연결을 이용하는 사용자의 경험을 증가시킨다. 내용을 압축하는데 필요한 CPU시간을 절약하기 위해 생성된 HTML의 GZIP 압축 버전을 캐시함에 따라 Cache_OutputCompressionCache_Output 클래스의 상관성을 확장시킨다. 맞춤식 솔루션 이전에 나는 PEAR Cache 프래임워크가 어떻게 맞춤식 캐싱 솔루션을 개발하기 위해 사용될 수 있는지에 대해 설명하였다. 그때 나는 SELECT 쿼리 결과를 캐시하는 MySQL_Query_Cache클래스를 선택하여 설명했다. 그렇다면 이제 클래스 변수인 생성자와 소멸자부터 시작해 보자. 생성자는 Cache_FunctionCache_Output클래스 앞에서 캐시 컨테이너 옵션을 옮기기 위해 사용된다. 소멸자는 MySQL 연결을 종료하고 필요하다면 캐시의 가비지 컬렉션을 작동시킨다.

<?php require_once 'Cache.php'; class MySQL_Query_Cache extends Cache { var $connection = null; var $expires = 3600; var $cursor = 0; var $result = array(); function MySQL_Query_Cache($container = 'file', $container_options = array('cache_dir'=> '.', 'filename_prefix' => 'cache_'), $expires = 3600) { $this->Cache($container, $container_options); $this->expires = $expires; } function _MySQL_Query_Cache() { if (is_resource($this->connection)) { mysql_close($this->connection); } $this->_Cache(); } } ?>
 
실제적으로 쿼리를 수행하고 캐시하는 핵심적인 부분을 살펴보기 이전에 좀더 도움을 주는 함수에 대해 살펴보자.

<?php function connect($hostname, $username, $password, $database) { $this->connection = mysql_connect($hostname, $username, $password) or trigger_error('Could not connect to database.', E_USER_ERROR); mysql_select_db($database, $this->connection) or trigger_error('Could not select database.', E_USER_ERROR); } function fetch_row() { if ($this->cursor < sizeof($this->result)) { return $this->result[$this->cursor++]; } else { return false; } } function num_rows() { return sizeof($this->result); } ?>
우리는 MySQL 데이터베이스에 연결하거나 캐시된 결과로부터 열을 불러오고 세트 안에 있는 열의 숫자를 가져오는데 필요한 함수를 이미 알고 있다. 그렇다면 데이터베이스 쿼리가 어떻게 수행하고 캐시하는지 살펴보도록 하자.

<?php function query($query) { if (stristr($query, 'SELECT')) { // Compute unique cache identifier for this query $cache_id = md5($query); // Query the cache $this->result = $this->get($cache_id, 'mysql_query_cache'); if ($this->result == NULL) { // Cache Miss $this->cursor = 0; $this->result = array(); if (is_resource($this->connection)) { // Use mysql_unbuffered_query(), if available if (function_exists('mysql_unbuffered_query')) {$result = mysql_unbuffered_query($query, $this->connection); } else {$result = mysql_query($query, $this->connection); } // Fetch all result rows while ($row = mysql_fetch_assoc($result)) {$this->result[] = $row; } // Free MySQL Result Resource mysql_free_result($result); // Store result set in cache $this->save($cache_id, $this->result, $this->expires, 'mysql_query_cache'); } } } else { // No SELECT query, don't cache it return mysql_query($query, $this->connection); } } ?>

 
예제 3: 활성중인 MySQL 쿼리 캐시

<?php require_once 'MySQL_Query_Cache.php'; $cache = new MySQL_Query_Cache(); $cache->connect('hostname', 'username', 'password', 'database'); $cache->query('select * from table'); while ($row = $cache->fetch_row()) { echo '<p>'; print_r($row); echo '</p>'; } ?>
이상 주어진 정보만으로도 여러분은 대부분의 응용 프로그램에서 PHP웹 페이지를 캐싱할 수 있을 것이다. 세바스찬 베르그만(Sebastian Bergmann)은 23세의 독일출신 컴퓨터 공학도이며 PHP 프로젝트에 참여하고 있다. 이외에도 온라인 및 오프라인의 자유기고가로 활동하고 있으며 독일 PHP 연합 고문단(www.php-ev.de)의 일원으로 phpOpenTracker 소프트웨어(www.phpOpenTracker.de)를 개발하고 있다. 
 


출처 : 한빛 네트워크


Trackback 1 Comment 1
  1. Favicon of http://blog.naver.com/jjusik2 프시쵸 2012.04.26 18:54 address edit & del reply

    좋은 정보 감사합니다~. imagick을 설치해서 문서 이미지(tiff)에 원하는 폰트 불러와서 문서에 체크, 글자를 넣으려 하는데 첫 길목부터 저를 힘들게 하더군요. =ㅅ= 그래도 이렇게 좋으신 분들이 있어서 제가 덜 고생을 하는 것 같습니다.

2009. 5. 15. 14:24

ImageMagick을 이용한 썸네일(thumbnail) 만들기

UploadProc 는 업로드 되는 부분을 만들어 놓은 class 입니다.

업로드 부분은 자신에게 맞는것으로 수정 하시면 됩니다.

 

if($mode=="submit"){
// echo $_FILES['userfile']['name'];
// exit;
 if($_FILES['userfile']["name"] != "") {
  $UploadProc = new UploadProc("/home/flowermall/admin_new/temp/imageMagick/original","1073741824");
  $image_name = $UploadProc->Upload($_FILES['userfile']);
  
  $full_filename=explode(".","$image_name");
  $ext=$full_filename[sizeof($full_filename)-1];
  $file_name=str_replace(".".$ext,"",$image_name);
  
  
  $image_name_110=$file_name."_110.$ext";
  $image_name_150=$file_name."_150.$ext";  
  $image_name_200=$file_name."_200.$ext";
  $image_name_250=$file_name."_250.$ext";  
  $image_name_550=$file_name."_550.$ext";
  $image_name_650=$file_name."_650.$ext";
  
  $image_name_550_mark=$file_name."_550_mark.$ext";
  
  exec("convert -thumbnail 110 -sharpen 100 ./original/$image_name ./110/$image_name_110");
  exec("convert -thumbnail 150 ./original/$image_name ./150/$image_name_150");
  exec("convert -thumbnail 200 ./original/$image_name ./200/$image_name_200");
  exec("convert -thumbnail 250 ./original/$image_name ./250/$image_name_250");
  exec("convert -thumbnail 550 ./original/$image_name ./550/$image_name_550");
  exec("convert -thumbnail 650 ./original/$image_name ./650/$image_name_650");
  
  exec("composite -gravity SouthWest mark_550.gif ./550/$image_name_550 ./550/$image_name_550_mark");
  exec("composite -gravity SouthWest mark_550.gif ./650/$image_name_650 ./650/$image_name_650_mark");
  
  echo "
   <IMG SRC='./110/$image_name_110'><br>
   <IMG SRC='./150/$image_name_150'><br>
   <IMG SRC='./200/$image_name_200'><br>
   <IMG SRC='./250/$image_name_250'><br>
   <IMG SRC='./550/$image_name_550_mark'><br>
   <IMG SRC='./650/$image_name_650'><br>
  ";
  
 }
}
?>

<html>
<head>
<title>이미지 업로드 resize 테스트</title>
<script language=javascript>
function addPhoto(url){
 document.preview.src=url;
 document.preview.style.display='block';
}
</script>
</head>
<body>
<form method=post action='<?=$_SERVER[PHP_SELF]?>' enctype='multipart/form-data'>
<input type=hidden name=mode value='submit'>
<INPUT TYPE=FILE name=userfile onChange="addPhoto(this.value)"><br>
<img name=preview src='' width=300 style="display:none"><br>
<INPUT TYPE=SUBMIT><br>
</form>
</body>
</html>


소스상에서

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
function MakeThum($FileName)
{
        $ThumFileName = $FileName . ".gif";
        
        $FileName = "../screenshot/" . $FileName;
        $ThumFileName = "../screenshot/" . $ThumFileName;
        
        exec ("convert -geometry 400x $FileName $ThumFileName");
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

정도면 가능합니다.

조금 설명을 드린다면 exec는 외부 프로그램을 실행시키는 명령어 입니다.

convert는 좀전에 설치한 imagemagick중의 하나인데 메뉴얼에보면
이놈의 옵션중에 하나인 geometry는

geometry <width>x<height>{+-}<x>{+-}<y>{%}{@} {!}{<}{>}  
   preferred size and location of the Image window.

preferred size and location of the Image window.

By default, the window size is the image size and the location is chosen by you when it is mapped.  

By default, the width and height are maximum values. That is, the image is expanded or contracted to fit the width and height value while maintaining the aspect ratio of the image. Append an exclamation point to the geometry to force the image size to exactly the size you specify. For example, if you specify 640x480! the image width is set to 640 pixels and height to 480.  

If only the width is specified, the width assumes the value and the height is chosen to maintain the aspect ratio of the image. Similarly, if only the height is specified (e.g., -geometry x256), the width is chosen to maintain the aspect ratio.  

To specify a percentage width or height instead, append %. The image size is multiplied by the width and height percentages to obtain the final image dimensions. To increase the size of an image, use a value greater than 100 (e.g. 125%). To decrease an image's size, use a percentage less than 100.  

Use @ to specify the maximum area in pixels of an image.  

Use > to change the dimensions of the image only if its width or height exceeds the geometry specification. < resizes the image only if both of its dimensions are less than the geometry specification. For example, if you specify '640x480>' and the image size is 256x256, the image size does not change. However, if the image is 512x512 or 1024x1024, it is resized to 480x480. Enclose the geometry specification in quotation marks to prevent the < or > from being interpreted by your shell as a file redirection.  

When used with animate and display, offsets are handled in the same manner as in X(1) and the -gravity option is not used. If the x is negative, the offset is measured leftward from the right edge of the screen to the right edge of the image being displayed. Similarly, negative y is measured between the bottom edges. The offsets are not affected by "%"; they are always measured in pixels.

When used as a composite option, -geometry gives the dimensions of the image and its location with respect to the composite image. If the -gravity option is present with NorthEast, East, or SouthEast gravity, the x represents the distance from the right edge of the image to the right edge of the composite image. Similarly, if the -gravity option is present with SouthWest, South, or SouthEast gravity, y is measured between the bottom edges. Accordingly, a positive offset will never point in the direction outside of the image. The offsets are not affected by "%"; they are always measured in pixels. To specify the dimensions of the composite image, use the -resize option.  

When used as a convert, import or mogrify option, -geometry is synonymous with -resize and specifies the size of the output image. The offsets, if present, are ignored.  

When used as a montage option, -geometry specifies the image size and border size for each tile; default is 256x256+0+0. Negative offsets (border dimensions) are meaningless. The -gravity option affects the placement of the image within the tile; the default gravity for this purpose is Center. If the "%" sign appears in the geometry specification, the tile size is the specified percentage of the original dimensions of the first tile. To specify the dimensions of the montage, use the -resize option.  

라고 되어있는데...

convert -geometry 400x                 

정확한 해석은...제가 아까도 말씀드렸지만 영어가 딸려서...^^...공부해야되...ㅡ,.ㅡ
뭐 대충
        convert -geometry 400x         
요렇게 쓰면 썸네일을 만들때 가로가 400에 고정되고 세로는 그 비율에 맞게 되고
        convert -geometry x400
요렇게 쓰면 썸네일을 만들때 세로가 400에 고정되고 가로는 그 비율에 맞게 되는

암튼 써보시고 더 좋은 팁있으면 올려주세요..


Trackback 0 Comment 0