DmImage

github.com/demouth/DmImage

version 2.0

github download @demouth


ツイート
このエントリーをはてなブックマークに追加

Fork me on GitHub

目次

DmImageについて

include方法

PSR-0に準拠していますので、Zendのオートローダー等で自動で読み込めると思います。
PHP5.3以下でも使えるようにnamespaceは使用していませんが、SplClassLoaderを使う場合と使わない場合はそれぞれこんな感じです。お好きな方法で読み込んでください。
<?php
// SplClassLoaderを使用する場合
require_once 'SplClassLoader.php';
$DmDirPath = '/path/to/lib/';
$classLoader = new SplClassLoader(null, $DmDirPath);
$classLoader->register();
<?php
// SplClassLoaderを使用せず、1ファイル毎読み込む場合
$DmDirPath = '/path/to/lib/';
require_once $DmDirPath.'Dm/Color.php';
require_once $DmDirPath.'Dm/Image.php';
require_once $DmDirPath.'Dm/Image/Graphic/Interface.php';
require_once $DmDirPath.'Dm/Image/Graphic/Text.php';
require_once $DmDirPath.'Dm/Image/Graphic/Shape.php';
require_once $DmDirPath.'Dm/Image/File.php';
require_once $DmDirPath.'Dm/Image/Filter/Abstract.php';
require_once $DmDirPath.'Dm/Image/Filter/Fit.php';
require_once $DmDirPath.'Dm/Image/Filter/Crop.php';
require_once $DmDirPath.'Dm/Image/Filter/InstagramNormal.php';
require_once $DmDirPath.'Dm/Image/Filter/InstagramLoFi.php';
require_once $DmDirPath.'Dm/Image/Filter/InstagramWalden.php';
require_once $DmDirPath.'Dm/Image/Filter/InstagramToaster.php';
Composerを利用する場合はcomposer.jsonのrequireに "demouth/dmimage": "dev-master" と書き、updateしておけばrequireしなくても使えます。
FuelPHP1.6の場合、composer.jsonのrequireの部分を抜き出すと例として下記のようになります。
    "require": {
        "php": ">=5.3.3",
        "monolog/monolog": "1.5.*",
        "fuelphp/upload": "2.0",
        "demouth/dmimage": "dev-master"
    },

使い方1 〜 画像の表示

サイズが横400x縦300で、色が0099FFで、透明度がFF(つまり透明ではない)の画像を作成し、出力している例です。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->display();
exit;

使い方2 〜 DataSchemeURIを使った表示

DataSchemeURIを使った出力にも対応していますので、タグに直接画像を埋め込む事ができます。
なお、この機能を使用する際、ライブラリ内のディレクトリに一時ファイルを作成しますのでディレクトリの権限設定にご注意ください。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);

?><!DOCTYPE html>
<head>
	<meta charset="UTF-8" />
</head>
<body>
	
	DATA SCHEME URIで表示
	<br>
	<img src="<?= $image->toDataSchemeURI() ?>">
	
</body>
</html>
このコードで出力すると実際に出力されるimgタグは次のようになっています。
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEs
CAYAAADtt+XCAAAEPElEQVR4Xu3VMQ3AMBDAwDT8CRTtl0CkqJ7vZu9+1juzAOCn
fQsA4MRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRA
AEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDE
QABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASA
xEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwE
gMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgM
BIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABI
DASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAA
SAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRA
AEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDE
QABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASA
xEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwE
gMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgM
BIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABI
DASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAA
SAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRA
AEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDE
QABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASA
xEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwE
gMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgM
BIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABI
DASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASAxEAA
SAwEgMRAAEgMBIDEQABIDASAxEAASAwEgMRAAEgMBIDEQABIDASA5AOLiwTvg1Oq
XwAAAABJRU5ErkJggg==">

使い方3 〜 画像のファイル出力

生成したインスタンスは画像ファイルとしても出力可能です。
下記の例ではpng画像1枚、jpg画像2枚、gif画像1枚をサーバー上にファイル出力しています。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->textGraphics
	->setColor(0xFFFFFFFF)
	->setFontSize(30)
	->textTo(80, 150, 'Hello world.')
;
$image->saveTo('/path/to/dir/saved_image.png');
$image->saveTo('/path/to/dir/saved_image.jpg');
$image->saveTo('/path/to/dir/saved_image.jpeg');
$image->saveTo('/path/to/dir/saved_image.gif');

使い方4 〜 ダウンロードダイアログからの画像ダウンロード

下記のコードで画像がブラウザへダウンロードされます。
下記の例ではjpg形式で画像クオリティを50/100でブラウザへのダウンロードを行なっています。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->startDownload('download','jpg',50);

使い方5 〜 背景色指定の一例

色指定の方法は0xFF001122のような16進数指定以外にも、Dm_Colorクラスを使用すれば色の微調整が可能です。
<?php
$color = Dm_Color::argb(1, 255, 0, 0); //RGB指定
$color->v *= 0.5; //明度を半分に(HSV)
$image = new Dm_Image(400,300, $color->toInt());
$image->display();
exit;

使い方6 〜 四角形の描画

XY座標を指定して画像へ四角形を描画します。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->graphics->drawRect(20, 100, 360, 100);
$image->display();
exit;

使い方7 〜 図形描画時のstyle指定

描画前に塗りの色と線の色を指定し、図形描画できます。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->graphics
	->lineStyle(0,0)
	->fillStyle(0xFFFFFFFF)
	->drawRect(70, 40, 200, 150)
	->lineStyle(10,0x6600FFFF)
	->fillStyle(0)
	->drawRect(100, 70, 200, 150)
	->lineStyle(20,0xFF3300FF)
	->fillStyle(0x9900AAFF)
	->drawRect(130, 100, 200, 150)
;
$image->display();
exit;

使い方8 〜 基本図形の描画

色々な図形を描画できます。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->graphics
	->lineStyle(1,0xFFFFFFFF)
	->fillStyle(0xFF66BBFF)
	->drawRect(10, 10, 190, 140)
	->drawCircle(100, 225, 50)
	->drawEllipse(300, 75, 150, 100)
	->drawPie(300, 225, 150, 100, 0, 135)
;
$image->display();
exit;

使い方9 〜 直線図形の描画

直線を使って複雑な図形の描画も可能です。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->graphics
	->lineStyle(1,0xFFFFFFFF)
	->fillStyle(0x99001199)
	->beginLineFill()
	->moveTo(200, 10)
	->lineTo(230, 100)
	->lineTo(340, 100)
	->lineTo(250, 160)
	->lineTo(300, 290)
	->lineTo(200, 190)
	->lineTo(100, 290)
	->lineTo(150, 160)
	->lineTo(60,  100)
	->lineTo(170, 100)
	->lineTo(200, 10)
	->endLineFill()
;
$image->display();
exit;

使い方10 〜 テキストの描画

文字の描画もできます。
GDでテキストを描画するのは面倒ですが、ライブラリ内にフォントが組み込んでいることで簡単に描画できます。
<?php
$image = new Dm_Image(400,300, 0xFF0099FF);
$image->textGraphics
	//->setFontFile('path/to/fontfile.ttf') //フォント指定したい場合
	->setColor(0xFFFFFFFF)
	->setFontSize(30)
	->textTo(70, 230, 'Hello world.',45)
	->setColor(0xFF000000)
	->textTo(244, 210, '日本語。',45)
	->setColor(0xFFFFFFFF)
	->textTo(240, 210, '日本語。',45)
;
$image->display();
exit;

使い方11 〜 filterを使った画像のリサイズ

filter機能を使うと画像の加工も簡単にできます。
デフォルトで画像のリサイズや切り抜きを行うクラスが用意されています。
下記の例では2つのfilterを組み合わせ、200x200に収まるサイズに画像をリサイズしています。
<?php
$originalImagePath = './horse.jpeg';
$width = 200;
$height = 200;
$fitFilter = new Dm_Image_Filter_Fit($width,$height,true);
$cropFilter = new Dm_Image_Filter_Crop($width,$height);

$image = new Dm_Image_File($originalImagePath);
$image->applyFilters(array(
		$fitFilter,
		$cropFilter
	));

?><!DOCTYPE html>
<head>
	<meta charset="UTF-8" />
</head>
<body>
	<div>
		元画像<br>
		<img src="<?=$originalImagePath?>">
	</div>
	<div>
		Filter適用後(縦<?=$width?> x 横<?=$height?> に収まるようにリサイズ)<br>
		<img src="<?=$image->toDataSchemeURI()?>" />
	</div>
</body>
</html>

使い方12 〜 Instagram風の画像加工フィルタ

Instagramっぽく画像を加工するクラスが3つ用意されています。
色の加工とフレームの組み合わせは変更可能です。
<?php
$originalImagePath = './horse.jpeg';
$filter1 = new Dm_Image_Filter_InstagramLoFi(300,1);
$filter2 = new Dm_Image_Filter_InstagramWalden(300,2);
$filter3 = new Dm_Image_Filter_InstagramToaster(300);

$image1 = new Dm_Image_File($originalImagePath);
$image1->applyFilter($filter1);
$image2 = new Dm_Image_File($originalImagePath);
$image2->applyFilter($filter2);
$image3 = new Dm_Image_File($originalImagePath);
$image3->applyFilter($filter3);

?><!DOCTYPE html>
<head>
	<meta charset="UTF-8" />
</head>
<body>
	<div>
		元画像<br>
		<img src="<?=$originalImagePath?>">
	</div>
	<div>
		Instagram風Filter適用後<br>
		<img src="<?=$image1->toDataSchemeURI()?>" />
		<img src="<?=$image2->toDataSchemeURI()?>" />
		<img src="<?=$image3->toDataSchemeURI()?>" />
	</div>
</body>
</html>

使い方13 〜 2枚の画像を合成

2枚の画像を合成できます。
下記の例では写真の上に半透明のロゴ画像を合成しています。
<?php
$filter = new Dm_Image_Filter_Fit(400,400);
$image = new Dm_Image_File(dirname(__FILE__).'/horse.jpeg');
$image->applyFilter($filter);

$logoImage = new Dm_Image_File(dirname(__FILE__).'/php.gif');
$image->draw($logoImage,20,20);

$image->display();
exit;

使い方14 〜 ドラえもん

描画メソッドを組み合わせるとドラえもんも描けます。
フォントはドラえもんフォントを使っています。
<?php

$colorBody = 0xFF0099FF;
$colorLine = 0xFF003399;
$colorWhite = 0xFFFFFFFF;
$colorEye  = 0xFF000000;
$colorRed  = 0xFFFF0000;
$colorYellow = 0xFFFFFF00;
$thickness = 3;
$image = new Dm_Image(500,600,0xFFFFFFFF);
$image->graphics
	
	//体
	->fillStyle($colorBody)
	->lineStyle($thickness,$colorLine)
	->beginLineFill()
	->moveTo(260, 440)
	->lineTo(260, 450)
	->lineTo(360, 450)
	->lineTo(360, 370)
	->lineTo(400, 410)
	->lineTo(440, 370)
	->lineTo(360, 290)
	->lineTo(140, 290)
	->lineTo(60 , 370)
	->lineTo(100, 410)
	->lineTo(140, 370)
	->lineTo(140, 450)
	->lineTo(240, 450)
	->lineTo(240, 440)
	->endLineFill()
	
	//手
	->fillStyle($colorWhite)
	->drawCircle(410, 380, 35)
	->drawCircle(90 , 380, 35)
	
	//ポケット
	->drawCircle(250, 330, 85)
	->drawPie(250, 350, 120, 100, 0, 180)
	->moveTo(190, 350)
	->lineTo(310, 350)
	
	//足
	->drawRect(260, 450, 100, 29)
	->drawPie(359, 465, 20, 30, -90, 90)
	->drawPie(262, 465, 20, 30, 90, -90)
	->drawRect(140, 450, 100, 29)
	->drawPie(239, 465, 20, 30, -90, 90)
	->drawPie(142, 465, 20, 30, 90, -90)
	
	//頭
	->fillStyle($colorBody)
	->drawEllipse(250, 150, 350, 280)
	->fillStyle($colorWhite)
	->drawEllipse(250, 190, 280, 190)
	
	//目
	->drawEllipse(290, 100, 80, 90)
	->drawEllipse(210, 100, 80, 90)
	->fillStyle($colorEye)
	->drawCircle(270, 110, 10)
	->drawCircle(230, 110, 10)
	
	//鼻・口・ひげ
	->fillStyle($colorRed)
	->drawCircle(250, 140, 15)
	->lineStyle(0)
	->fillStyle($colorWhite)
	->drawCircle(255, 135, 5)
	->lineStyle($thickness,$colorLine)
	->moveTo(250, 153)
	->lineTo(250, 250)
	->fillStyle(0)
	->drawPie(250, 200, 160, 100, 15, 165)
	->moveTo(300, 170)
	->lineTo(350, 150)
	->moveTo(300, 180)
	->lineTo(350, 180)
	->moveTo(300, 190)
	->lineTo(350, 210)
	->moveTo(200, 170)
	->lineTo(150, 150)
	->moveTo(200, 180)
	->lineTo(150, 180)
	->moveTo(200, 190)
	->lineTo(150, 210)
	
	//首輪
	->fillStyle($colorRed)
	->drawRect(141, 260, 222, 30)
	->drawPie(360, 275, 20, 30, -90,  90)
	->drawPie(142, 275, 20, 30,  90, -90)
	
	//鈴
	->fillStyle($colorYellow)
	->drawCircle(250, 290, 20)
	->moveTo(232, 280)
	->lineTo(268, 280)
	->moveTo(230, 285)
	->lineTo(270, 285)
	->moveTo(250, 300)
	->lineTo(250, 310)
	->drawCircle(250, 298, 5)
;
$image->textGraphics
	->setFontSize(70)
	->setFontFile('font/doraemoji/doraemoji.ttf') //フォント
	->setColor($colorLine)
	->textTo(20, 580, 'ドラえもん')
;

$image->display();
exit;

使い方15 〜 Processingのソースを移植

Processingのソースを移植しました。
http://processing.org/learning/topics/tree.html
<?php
define('WIDTH', 640);
define('HEIGHT', 360);

$theta = rand(1,20)*0.1;
$image = new Dm_Image(WIDTH,HEIGHT,0xFF000000);
draw();
$image->display();

function draw()
{
	global $image;
	
	$image->graphics
		->lineStyle(1,0xFFFFFFFF)
		->moveTo(WIDTH/2, HEIGHT)
		->lineTo(WIDTH/2, HEIGHT-120);
	$h = 120;
	branch($h,-M_PI/2,WIDTH/2,HEIGHT-120);
}
function branch($h,$rotate,$x,$y)
{
	global $image,$theta;
	if($h<2)return;
	
	$h *= 0.66;
	
	$movedX = cos($rotate+$theta)*$h + $x;
	$movedY = sin($rotate+$theta)*$h + $y;
	$image->graphics
		->moveTo($x, $y)
		->lineTo($movedX, $movedY);
	branch($h,$rotate+$theta,$movedX,$movedY);
	
	$movedX = cos($rotate-$theta)*$h + $x;
	$movedY = sin($rotate-$theta)*$h + $y;
	$image->graphics
		->moveTo($x, $y)
		->lineTo($movedX, $movedY);
	branch($h,$rotate-$theta,$movedX,$movedY);
}

下記の例では複数の静止画を出力し、アニメーションgifとして結合しています。

使い方16 〜 JavaScriptのソースを移植

JavaScriptのソースを移植しました。
http://cssdeck.com/labs/the-matrix
<?php
define('W', 640);
define('H', 360);
define('FONT_SIZE', 11);
define('FRAME', 200);

$STR = array('感','憂','位','中','上','医','受','柄','下','嫁','木','区','毛','弧');
$letters = array_fill(0,((int)W/FONT_SIZE),0);
$image = new Dm_Image(W,H,0xFF000000);
$graphics = $image->graphics;
$textGraphics = $image->textGraphics;
$graphics->fillStyle(0x22000000);
for($i=0;$i<FRAME;$i++) draw();
$image->display();

function draw()
{
	global $STR,$letters,$graphics,$textGraphics;
	
	$graphics->drawRect(0, 0, W, H);
	$l = count($letters);
	for($i=0;$i<$l;$i++){
		$str = $STR[rand(0,count($STR)-1)];
		$y = $letters[$i];
		$textGraphics
			->setColor(0xFF00FF00)
			->setFontSize(FONT_SIZE-3)
			->textTo($i*FONT_SIZE, $y, $str);
		$letters[$i] = ($y > H + rand(0,1e3)) ? 0 : $y+FONT_SIZE;
	}
}

下記の例では複数の静止画を出力し、アニメーションgifとして結合しています。

使い方17 〜 アニメーション表現

Flashのようなアニメーション表現も可能です。
<?php
define('W', 640);
define('H', 360);
define('C', 200);
define('D', 50);

$image = new Dm_Image(W,H,0xFF000000);
$graphics = $image->graphics;
$graphics
	->lineStyle(0)
	->fillStyle(0x66FFFFFF);

$nodeList = array();
for ($i=0; $i < C; $i++) { 
	$nodeList[] = array(
		rand(-20,W+20),
		rand(-20,H+20),
		0
	);
}

for ($i=0; $i < C; $i++) {
	$node = &$nodeList[$i];
	
	for ($j=$i; $j < C; $j++) {
		if($i==$j)continue;
		$nNode = &$nodeList[$j];
		$x = $node[0] - $nNode[0];
		$y = $node[1] - $nNode[1];
		$diff = sqrt($x*$x+$y*$y);
		if($diff < D){
			$node[2] += 1;
			$nNode[2] += 1;
			$graphics
				->lineStyle(
					min(10*(D-$diff)/D,4),
					Dm_Color::argb((D-$diff)/D*0.6+0.2,255,255,255)->toInt()
				)
				->moveTo($node[0], $node[1])
				->lineTo($nNode[0], $nNode[1])
			;
		}
	}
}

$graphics->lineStyle(0,0x11FFFFFF);
for ($i=0; $i < C; $i++) {
	$node = $nodeList[$i];
	$graphics->drawCircle($node[0], $node[1], 2+$node[2]*$node[2]*0.3);
}

$image->display();

下記の例では複数の静止画を出力し、アニメーションgifとして結合しています。