* @version 1.0 $ 2010-10-17 19:11:51 $
*/
class canvas
{
/**
* Variáveis para armazenamento de arquivos/imgs
**/
private $origem, $img, $img_temp;
/**
* Armazenam as dimensões da imagem atual e da nova imagem caso exista
**/
private $largura, $altura, $nova_largura, $nova_altura, $tamanho_html;
/**
* Variáveis para o posicionamento do crop
**/
private $pos_x, $pos_y;
/**
* Informações sobre o arquivo enviado e diretório
**/
private $formato, $extensao, $tamanho, $arquivo, $diretorio;
/**
* Array RGB para resize com preenchimendo do fundo
**/
private $rgb;
/**
* Coordenadas para posicionamento do crop
**/
private $posicao_crop;
/**
* @var canvas
*/
private static $instance;
/**
* Método singleton para que apenas uma instancia da classe seja utilizada no servidor.
* @param String $origem
* @return canvas
*/
public static function Instance($origem = '')
{
if (empty(self::$instance))
self::$instance = new canvas($origem);
else
self::$instance->resetar();
return self::$instance;
}
/**
* Construtor
* @param $string caminho da imagem a ser carregada [opcional]
* @return void
**/
public function __construct($origem = '')
{
$this->origem = $origem;
if ($this->origem) {
$this->dados();
}
// RGB padrão -> branco
$this->rgb(255, 255, 255);
} // fim construtor
/**
* Reseta variáveis para poder reutilizar objeto em encadeamentos longos
* @return void
**/
public function resetar()
{
$this->origem = $this->img = $this->img_temp = $this->largura = $this->altura = $this->nova_largura = $this->nova_altura = $this->tamanho_html = $this->pos_x = $this->pos_y = $this->formato = $this->extensao = $this->tamanho = $this->arquivo = $this->diretorio = $this->posicao_crop = NULL;
$this->rgb(255, 255, 255);
} // fim resetar
/**
* Retorna dados da imagem
* @return void
**/
private function dados()
{
// verifica se imagem existe
if (is_file($this->origem)) {
// dados do arquivo
$this->dadosArquivo();
// verifica se é imagem
if (!$this->eImagem()) {
trigger_error('Erro: Arquivo ' . $this->origem . ' não é uma imagem!', E_USER_ERROR);
} else {
// busca dimensões da imagem enviada
$this->dimensoes();
// cria imagem para php
$this->criaImagem();
}
} else {
trigger_error('Erro: Arquivo de imagem não encontrado!', E_USER_ERROR);
}
} // fim dadosImagem
/**
* Carrega uma nova imagem, fora do construtor
* @param String caminho da imagem a ser carregada
* @return Object instância atual do objeto, para métodos encadeados
**/
public function carrega($origem = '')
{
$this->origem = $origem;
$this->dados();
return $this;
} // fim carrega
/**
* Busca dimensões e formato real da imagem
* @return void
**/
private function dimensoes()
{
$dimensoes = getimagesize($this->origem);
$this->largura = $dimensoes[0];
$this->altura = $dimensoes[1];
/**
* 1 = gif, 2 = jpeg, 3 = png, 6 = BMP
* http://br2.php.net/manual/en/function.exif-imagetype.php
**/
$this->formato = $dimensoes[2];
$this->tamanho_html = $dimensoes[3];
} // fim dimensoes
/**
* Busca dados do arquivo
* @return void
**/
private function dadosArquivo()
{
// imagem de origem
$pathinfo = pathinfo($this->origem);
$this->extensao = array_key_exists('extension', $pathinfo) ? strtolower($pathinfo['extension']) : strtolower(str_replace('image/', '', $obj['mime']));
$this->arquivo = $pathinfo['basename'];
$this->diretorio = $pathinfo['dirname'];
} // fim dadosArquivo
/**
* Verifica se o arquivo indicado é uma imagem
* @return Boolean true/false
**/
private function eImagem()
{
// filtra extensão
$valida = getimagesize($this->origem);
if (!is_array($valida) || empty($valida)) {
return false;
} else {
return true;
}
} // fim validaImagem
/**
* Cria uma nova imagem para ser trabalhada com textos, etc.
* OBS: a cor da imagem deve ser passada antes, via rgb() ou hex()
* @param String $largura da imagem a ser criada
* @param String $altura da imagem a ser criada
* @return Object instância atual do objeto, para métodos encadeados
**/
public function novaImagem($largura, $altura)
{
$this->largura = $largura;
$this->altura = $altura;
$this->img = imagecreatetruecolor($this->largura, $this->altura);
$cor_fundo = imagecolorallocate($this->img, $this->rgb[0], $this->rgb[1], $this->rgb[2]);
imagefill($this->img, 0, 0, $cor_fundo);
$this->extensao = 'jpg';
return $this;
} // fim novaImagem
/**
* Carrega uma imagem via URL
* OBS: depente das configurações do servidor para acesso remoto de arquivos
* @param String $url endereço da imagem
* @return Object instância atual do objeto, para métodos encadeados
**/
public function carregaUrl($url)
{
$this->origem = $url;
$pathinfo = pathinfo($this->origem);
$this->extensao = strtolower($pathinfo['extension']);
switch ($this->extensao) {
case 'jpg':
case 'jpeg':
$this->formato = 2;
break;
case 'gif':
$this->formato = 1;
break;
case 'png':
$this->formato = 3;
break;
case 'bmp':
$this->formato = 6;
break;
default:
break;
}
$this->criaImagem();
$this->largura = imagesx($this->img);
$this->altura = imagesy($this->img);
return $this;
} // fim carregaUrl
/**
* Cria objeto de imagem para manipulação no GD
* @return void
**/
private function criaImagem()
{
switch ($this->formato) {
case 1:
$this->img = imagecreatefromgif($this->origem);
$this->extensao = 'gif';
break;
case 2:
$this->img = imagecreatefromjpeg($this->origem);
$this->extensao = 'jpg';
break;
case 3:
$this->img = imagecreatefrompng($this->origem);
$this->extensao = 'png';
break;
case 6:
$this->img = imagecreatefrombmp($this->origem);
$this->extensao = 'bmp';
break;
default:
trigger_error('Arquivo inválido!', E_USER_ERROR);
break;
}
} // fim criaImagem
/**
* Armazena os valores RGB para redimensionamento com preenchimento
* @param Valores R, G e B
* @return Object instância atual do objeto, para métodos encadeados
**/
public function rgb($r, $g, $b)
{
$this->rgb = array(
$r,
$g,
$b
);
return $this;
} // fim rgb
/**
* Converte hexadecimal para RGB
* @param String $cor cor hexadecimal
* @return Object instância atual do objeto, para métodos encadeados
**/
public function hexa($cor)
{
$cor = str_replace('#', '', $cor);
if (strlen($cor) == 3)
$cor .= $cor; // #fff, #000 etc.
$this->rgb = array(
hexdec(substr($cor, 0, 2)),
hexdec(substr($cor, 2, 2)),
hexdec(substr($cor, 4, 2))
);
return $this;
} // fim hexa
/**
* Armazena posições x e y para crop
* @param Int x - posicao x do crop
* @param Int y - posicao y do crop
* @param Int w - width - larguraOrigem (by OctaAugusto)
* @param Int h - height - alturaOrigem (by OctaAugusto)
* @return Object instância atual do objeto, para métodos encadeados
**/
public function posicaoCrop($x, $y, $w = 0, $h = 0)
{
// sem largura ou altura setada manualmente, pega original da imagem
if (!$w)
$w = $this->largura;
if (!$h)
$h = $this->altura;
$this->posicao_crop = array(
$x,
$y,
$w,
$h
);
return $this;
} // fim posicao_crop
/**
* Redimensiona imagem
* @param Int $nova_largura valor em pixels da nova largura da imagem
* @param Int $nova_altura valor em pixels da nova altura da imagem
* @param String $tipo método para redimensionamento (padrão [vazio], preenchimento ou crop)
* @return Object instância atual do objeto, para métodos encadeados
**/
public function redimensiona($nova_largura = 0, $nova_altura = 0, $tipo = '')
{
// seta variáveis passadas via parâmetro
$this->nova_largura = $nova_largura;
$this->nova_altura = $nova_altura;
// verifica se passou altura ou largura como porcentagem
// largura %
$pos = strpos($this->nova_largura, '%');
if ($pos !== false && $pos > 0) {
$porcentagem = (( int ) str_replace('%', '', $this->nova_largura)) / 100;
$this->nova_largura = round($this->largura * $porcentagem);
}
// altura %
$pos = strpos($this->nova_altura, '%');
if ($pos !== false && $pos > 0) {
$porcentagem = (( int ) str_replace('%', '', $this->nova_altura)) / 100;
$this->nova_altura = $this->altura * $porcentagem;
}
// define se só passou nova largura ou altura
if (!$this->nova_largura && !$this->nova_altura) {
return false;
}
// só passou altura
elseif (!$this->nova_largura) {
$this->nova_largura = $this->largura / ($this->altura / $this->nova_altura);
}
// só passou largura
elseif (!$this->nova_altura) {
$this->nova_altura = $this->altura / ($this->largura / $this->nova_largura);
}
// redimensiona de acordo com tipo
switch ($tipo) {
case 'crop':
$this->redimensionaCrop();
break;
case 'preenchimento':
$this->redimensionaPreenchimento();
break;
case 'proporcional':
// modo proporcional sem preenchimento adicionado por Fernando VR (goo.gl/iDtmP)
$this->redimensionaProporcional();
break;
default:
$this->redimensionaSimples();
break;
}
// atualiza dimensões da imagem
$this->altura = $this->nova_altura;
$this->largura = $this->nova_largura;
return $this;
} // fim redimensiona
/**
* Redimensiona imagem, modo padrão, sem crop ou preenchimento
* (distorcendo caso tenha passado ambos altura e largura)
* @return void
**/
private function redimensionaSimples()
{
// cria imagem de destino temporária
$this->img_temp = imagecreatetruecolor($this->nova_largura, $this->nova_altura);
imagecopyresampled($this->img_temp, $this->img, 0, 0, 0, 0, $this->nova_largura, $this->nova_altura, $this->largura, $this->altura);
$this->img = $this->img_temp;
} // fim redimensiona()
/**
* Adiciona cor de fundo à imagem
* @return void
**/
private function preencheImagem()
{
$cor_fundo = imagecolorallocate($this->img_temp, $this->rgb[0], $this->rgb[1], $this->rgb[2]);
imagefill($this->img_temp, 0, 0, $cor_fundo);
} // fim preencheImagem
/**
* Redimensiona imagem sem cropar, proporcionalmente,
* preenchendo espaço vazio com cor rgb especificada
* @return void
**/
private function redimensionaPreenchimento()
{
// cria imagem de destino temporária
$this->img_temp = imagecreatetruecolor($this->nova_largura, $this->nova_altura);
if($this->extensao == 'png'){
$color = imagecolorallocatealpha($this->img_temp, 0, 0, 0, 127);
imagefill($this->img_temp, 0, 0, $color);
}else{
// adiciona cor de fundo à nova imagem
$this->preencheImagem();
}
// salva variáveis para centralização
$dif_x = $dif_w = $this->nova_largura;
$dif_y = $dif_h = $this->nova_altura;
/**
* Verifica altura e largura
* Calculo corrigido por Gilton Guma
*/
if (($this->largura / $this->nova_largura) > ($this->altura / $this->nova_altura)) {
$fator = $this->largura / $this->nova_largura;
} else {
$fator = $this->altura / $this->nova_altura;
}
$dif_w = $this->largura / $fator;
$dif_h = $this->altura / $fator;
// copia com o novo tamanho, centralizando
$dif_x = ($dif_x - $dif_w) / 2;
$dif_y = ($dif_y - $dif_h) / 2;
// Resample PNG
imagealphablending($this->img_temp, false);
imagesavealpha($this->img_temp, true);
imagecopyresampled($this->img_temp, $this->img, $dif_x, $dif_y, 0, 0, $dif_w, $dif_h, $this->largura, $this->altura);
$this->img = $this->img_temp;
} // fim redimensionaPreenchimento()
/**
* Redimensiona imagem sem cropar, proporcionalmente e sem preenchimento.
* Modo proporcional adicionado por Fernando VR ( http://goo.gl/iDtmP )
* @return void
**/
private function redimensionaProporcional()
{
/**
* Verifica altura e largura proporcional.
**/
$ratio_orig = $this->largura / $this->altura;
if ($this->nova_largura / $this->nova_altura > $ratio_orig) {
$dif_w = $this->nova_altura * $ratio_orig;
$dif_h = $this->nova_altura;
} else {
$dif_w = $this->nova_largura;
$dif_h = $this->nova_largura / $ratio_orig;
}
// cria imagem de destino temporária
$this->img_temp = imagecreatetruecolor($dif_w, $dif_h);
// Resample PNG
imagealphablending($this->img_temp, false);
imagesavealpha($this->img_temp, true);
imagecopyresampled($this->img_temp, $this->img, 0, 0, 0, 0, $dif_w, $dif_h, $this->largura, $this->altura);
$this->img = $this->img_temp;
} // fim redimensionaProporcional()
/**
* Calcula a posição do crop
* Os índices 0 e 1 correspondem à posição x e y do crop na imagem
* Os índices 2 e 3 correspondem ao tamanho do crop
* @return void
**/
private function calculaPosicaoCrop()
{
// média altura/largura
$hm = $this->altura / $this->nova_altura;
$wm = $this->largura / $this->nova_largura;
// 50% para cálculo do crop
$h_height = $this->nova_altura / 2;
$h_width = $this->nova_largura / 2;
// calcula novas largura e altura
if (!is_array($this->posicao_crop)) {
if ($wm > $hm) {
$this->posicao_crop[2] = $this->largura / $hm;
$this->posicao_crop[3] = $this->nova_altura;
$this->posicao_crop[0] = ($this->posicao_crop[2] / 2) - $h_width;
$this->posicao_crop[1] = 0;
}
// largura <= altura
elseif (($wm <= $hm)) {
$this->posicao_crop[2] = $this->nova_largura;
$this->posicao_crop[3] = $this->altura / $wm;
$this->posicao_crop[0] = 0;
$this->posicao_crop[1] = ($this->posicao_crop[3] / 2) - $h_height;
}
}
} // fim calculaPosicaoCrop
/**
* Redimensiona imagem, cropando para encaixar no novo tamanho, sem sobras
* baseado no script original de Noah Winecoff
* http://www.findmotive.com/2006/12/13/php-crop-image/
* atualizado para receber o posicionamento X e Y e/ou Coordenadas Inteligentes
* do crop na imagem.
* Coordenadas Inteligentes implementado por Aires Gonçalves
* @return void
**/
private function redimensionaCrop()
{
// calcula posicionamento do crop automaticamente
if (!is_array($this->posicao_crop)) {
$auto = 1;
$this->calculaPosicaoCrop();
}
// posicionamento do crop setado manualmente
else {
$auto = 0;
}
// cria imagem de destino temporária
$this->img_temp = imagecreatetruecolor($this->nova_largura, $this->nova_altura);
// adiciona cor de fundo à nova imagem
$this->preencheImagem();
//coordenadas inteligentes
switch ($this->posicao_crop[0]) {
case 'esquerdo':
$this->pos_x = 0;
break;
case 'direito':
$this->pos_x = $this->largura - $this->nova_largura;
break;
case 'meio':
$this->pos_x = ($this->largura - $this->nova_largura) / 2;
break;
default:
$this->pos_x = $this->posicao_crop[0];
break;
}
switch ($this->posicao_crop[1]) {
case 'topo':
$this->pos_y = 0;
break;
case 'inferior':
$this->pos_y = $this->altura - $this->nova_altura;
break;
case 'meio':
$this->pos_y = ($this->altura - $this->nova_altura) / 2;
break;
default:
$this->pos_y = $this->posicao_crop[1];
break;
}
$this->posicao_crop[0] = $this->pos_x;
$this->posicao_crop[1] = $this->pos_y;
// Resample PNG
imagealphablending($this->img_temp, false);
imagesavealpha($this->img_temp, true);
if ($auto)
imagecopyresampled($this->img_temp, $this->img, -$this->posicao_crop[0], -$this->posicao_crop[1], 0, 0, $this->posicao_crop[2], $this->posicao_crop[3], $this->largura, $this->altura);
else
imagecopyresampled($this->img_temp, $this->img, 0, 0, $this->posicao_crop[0], $this->posicao_crop[1], $this->nova_largura, $this->nova_altura, $this->posicao_crop[2], $this->posicao_crop[3]);
$this->img = $this->img_temp;
} // fim redimensionaCrop
/**
* flipa/inverte imagem
* baseado no script original de Noah Winecoff
* http://www.php.net/manual/en/ref.image.php#62029
* @param String $tipo tipo de espelhamento: h - horizontal, v - vertical
* @return Object instância atual do objeto, para métodos encadeados
**/
public function flip($tipo = 'h')
{
$w = imagesx($this->img);
$h = imagesy($this->img);
$this->img_temp = imagecreatetruecolor($w, $h);
// vertical
if ('v' == $tipo) {
for ($y = 0; $y < $h; $y++) {
imagecopy($this->img_temp, $this->img, 0, $y, 0, $h - $y - 1, $w, 1);
}
}
// horizontal
elseif ('h' == $tipo) {
for ($x = 0; $x < $w; $x++) {
imagecopy($this->img_temp, $this->img, $x, 0, $w - $x - 1, 0, 1, $h);
}
}
$this->img = $this->img_temp;
return $this;
} // fim flip
/**
* gira imagem
* @param Int $graus grau para giro
* @return Object instância atual do objeto, para métodos encadeados
**/
public function gira($graus)
{
$cor_fundo = imagecolorallocate($this->img, $this->rgb[0], $this->rgb[1], $this->rgb[2]);
$this->img = imagerotate($this->img, $graus, $cor_fundo);
imagealphablending($this->img, true);
imagesavealpha($this->img, true);
$this->largura = imagesx($this->img);
$this->altura = imagesx($this->img);
return $this;
} // fim girar
/**
* adiciona texto à imagem
* @param String $texto texto a ser inserido
* @param Int $tamanho tamanho da fonte
* Ver: http://br2.php.net/imagestring
* @param Int $x posição x do texto na imagem
* @param Int $y posição y do texto na imagem
* @param Array/String $cor_fundo array com cores RGB ou string com cor hexadecimal
* @param Boolean $truetype true para utilizar fonte truetype, false para fonte do sistema
* @param String $fonte nome da fonte truetype a ser utilizada
* @return void
**/
public function legenda($texto, $tamanho = 5, $x = 0, $y = 0, $cor_fundo = '', $truetype = false, $fonte = '')
{
$cor_texto = imagecolorallocate($this->img, $this->rgb[0], $this->rgb[1], $this->rgb[2]);
/**
* Define tamanho da legenda para posições fixas e fundo da legenda
**/
if ($truetype === true) {
$dimensoes_texto = imagettfbbox($tamanho, 0, $fonte, $texto);
$largura_texto = $dimensoes_texto[4];
$altura_texto = $tamanho;
} else {
if ($tamanho > 5)
$tamanho = 5;
$largura_texto = imagefontwidth($tamanho) * strlen($texto);
$altura_texto = imagefontheight($tamanho);
}
if (is_string($x) && is_string($y)) {
list($x, $y) = $this->calculaPosicaoLegenda($x . '_' . $y, $largura_texto, $altura_texto);
}
/**
* Cria uma nova imagem para usar de fundo da legenda
**/
if ($cor_fundo) {
if (is_array($cor_fundo)) {
$this->rgb = $cor_fundo;
} elseif (strlen($cor_fundo) > 3) {
$this->hexa($cor_fundo);
}
$this->img_temp = imagecreatetruecolor($largura_texto, $altura_texto);
$cor_fundo = imagecolorallocate($this->img_temp, $this->rgb[0], $this->rgb[1], $this->rgb[2]);
imagefill($this->img_temp, 0, 0, $cor_fundo);
imagecopy($this->img, $this->img_temp, $x, $y, 0, 0, $largura_texto, $altura_texto);
}
// truetype ou fonte do sistema?
if ($truetype === true) {
$y = $y + $tamanho;
imagettftext($this->img, $tamanho, 0, $x, $y, $cor_texto, $fonte, $texto);
} else {
imagestring($this->img, $tamanho, $x, $y, $texto, $cor_texto);
}
return $this;
} // fim legenda
/**
* Calcula a posição da legenda de acordo com string passada via parâmetro
*
* @param String $posicao valores pré-definidos (topo_esquerda, meio_centro etc.)
* @param Integer $largura largura da imagem
* @param Integer $altura altura da imagem
* @return void
**/
private function calculaPosicaoLegenda($posicao, $largura, $altura)
{
// define X e Y para posicionamento
switch ($posicao) {
case 'topo_esquerda':
$x = 0;
$y = 0;
break;
case 'topo_centro':
$x = ($this->largura - $largura) / 2;
$y = 0;
break;
case 'topo_direita':
$x = $this->largura - $largura;
$y = 0;
break;
case 'meio_esquerda':
$x = 0;
$y = ($this->altura / 2) - ($altura / 2);
break;
case 'meio_centro':
$x = ($this->largura - $largura) / 2;
$y = ($this->altura - $altura) / 2;
break;
case 'meio_direita':
$x = $this->largura - $largura;
$y = ($this->altura / 2) - ($altura / 2);
break;
case 'baixo_esquerda':
$x = 0;
$y = $this->altura - $altura;
break;
case 'baixo_centro':
$x = ($this->largura - $largura) / 2;
$y = $this->altura - $altura;
break;
case 'baixo_direita':
$x = $this->largura - $largura;
$y = $this->altura - $altura;
break;
default:
return false;
break;
} // end switch posicao
return array(
$x,
$y
);
} // fim calculaPosicaoLegenda
/**
* adiciona imagem de marca d'água
* @param String $imagem caminho da imagem de marca d'água
* @param Int/String $x posição x da marca na imagem ou constante para marcaFixa()
* @param Int/Sring $y posição y da marca na imagem ou constante para marcaFixa()
* @return Boolean true/false dependendo do resultado da operação
* @param Int $alfa valor para transparência (0-100)
* -> se utilizar alfa, a função imagecopymerge não preserva
* -> o alfa nativo do PNG
* @return Object instância atual do objeto, para métodos encadeados
**/
public function marca($imagem, $x = 0, $y = 0, $alfa = 100)
{
// cria imagem temporária para merge
if ($imagem) {
if (is_string($x) && is_string($y)) {
return $this->marcaFixa($imagem, $x . '_' . $y, $alfa);
}
$pathinfo = pathinfo($imagem);
switch (strtolower($pathinfo['extension'])) {
case 'jpg':
case 'jpeg':
$marcadagua = imagecreatefromjpeg($imagem);
break;
case 'png':
$marcadagua = imagecreatefrompng($imagem);
break;
case 'gif':
$marcadagua = imagecreatefromgif($imagem);
break;
case 'bmp':
$marcadagua = imagecreatefrombmp($imagem);
break;
default:
trigger_error('Arquivo de marca d\'água inválido.', E_USER_ERROR);
return false;
}
} else {
return false;
}
// dimensões
$marca_w = imagesx($marcadagua);
$marca_h = imagesy($marcadagua);
// retorna imagens com marca d'água
if (is_numeric($alfa) && (($alfa > 0) && ($alfa < 100))) {
imagecopymerge($this->img, $marcadagua, $x, $y, 0, 0, $marca_w, $marca_h, $alfa);
} else {
imagecopy($this->img, $marcadagua, $x, $y, 0, 0, $marca_w, $marca_h);
}
return $this;
} // fim marca
/**
* adiciona imagem de marca d'água, com valores fixos
* ex: topo_esquerda, topo_direita etc.
* Implementação original por Giolvani
* @param String $imagem caminho da imagem de marca d'água
* @param String $posicao posição/orientação fixa da marca d'água
* [topo, meio, baixo] + [esquerda, centro, direita]
* @param Int $alfa valor para transparência (0-100)
* @return void
**/
private function marcaFixa($imagem, $posicao, $alfa = 100)
{
// dimensões da marca d'água
list($marca_w, $marca_h) = getimagesize($imagem);
// define X e Y para posicionamento
switch ($posicao) {
case 'topo_esquerda':
$x = 0;
$y = 0;
break;
case 'topo_centro':
$x = ($this->largura - $marca_w) / 2;
$y = 0;
break;
case 'topo_direita':
$x = $this->largura - $marca_w;
$y = 0;
break;
case 'meio_esquerda':
$x = 0;
$y = ($this->altura / 2) - ($marca_h / 2);
break;
case 'meio_centro':
$x = ($this->largura - $marca_w) / 2;
$y = ($this->altura / 2) - ($marca_h / 2);
break;
case 'meio_direita':
$x = $this->largura - $marca_w;
$y = ($this->altura / 2) - ($marca_h / 2);
break;
case 'baixo_esquerda':
$x = 0;
$y = $this->altura - $marca_h;
break;
case 'baixo_centro':
$x = ($this->largura - $marca_w) / 2;
$y = $this->altura - $marca_h;
break;
case 'baixo_direita':
$x = $this->largura - $marca_w;
$y = $this->altura - $marca_h;
break;
default:
return false;
break;
} // end switch posicao
// cria marca
$this->marca($imagem, $x, $y, $alfa);
return $this;
} // fim marcaFixa
/**
* Aplica filtros avançados como brilho, contraste, pixelate, blur
* Requer o GD compilado com a função imagefilter()
* http://br.php.net/imagefilter
* @param String $filtro constante/nome do filtro
* @param Integer $quantidade número de vezes que o filtro deve ser aplicado
* utilizado em blur, edge, emboss, pixel e rascunho
* @param $arg1, $arg2 e $arg3 - ver manual da função imagefilter
* @return Object instância atual do objeto, para métodos encadeados
**/
public function filtra($filtro, $quantidade = 1, $arg1 = NULL, $arg2 = NULL, $arg3 = NULL, $arg4 = NULL)
{
switch ($filtro) {
case 'blur':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_GAUSSIAN_BLUR);
}
} else {
imagefilter($this->img, IMG_FILTER_GAUSSIAN_BLUR);
}
break;
case 'blur2':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_SELECTIVE_BLUR);
}
} else {
imagefilter($this->img, IMG_FILTER_SELECTIVE_BLUR);
}
break;
case 'brilho':
imagefilter($this->img, IMG_FILTER_BRIGHTNESS, $arg1);
break;
case 'cinzas':
imagefilter($this->img, IMG_FILTER_GRAYSCALE);
break;
case 'colorir':
imagefilter($this->img, IMG_FILTER_COLORIZE, $arg1, $arg2, $arg3, $arg4);
break;
case 'contraste':
imagefilter($this->img, IMG_FILTER_CONTRAST, $arg1);
break;
case 'edge':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_EDGEDETECT);
}
} else {
imagefilter($this->img, IMG_FILTER_EDGEDETECT);
}
break;
case 'emboss':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_EMBOSS);
}
} else {
imagefilter($this->img, IMG_FILTER_EMBOSS);
}
break;
case 'negativo':
imagefilter($this->img, IMG_FILTER_NEGATE);
break;
case 'ruido':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_MEAN_REMOVAL);
}
} else {
imagefilter($this->img, IMG_FILTER_MEAN_REMOVAL);
}
break;
case 'suave':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_SMOOTH, $arg1);
}
} else {
imagefilter($this->img, IMG_FILTER_SMOOTH, $arg1);
}
break;
// SOMENTE 5.3 ou superior
case 'pixel':
if (is_numeric($quantidade) && $quantidade > 1) {
for ($i = 1; $i <= $quantidade; $i++) {
imagefilter($this->img, IMG_FILTER_PIXELATE, $arg1, $arg2);
}
} else {
imagefilter($this->img, IMG_FILTER_PIXELATE, $arg1, $arg2);
}
break;
default:
break;
}
return $this;
} // fim filtrar
/**
Adiciona o melhor filtro para as imagens o sharpen | Jefferson Oliveira
Usa GD image objects
**/
function imagesharpen()
{
$qualidade = array(
array(
-1,
-1,
-1
),
array(
-1,
16,
-1
),
array(
-1,
-1,
-1
)
);
$divisao = array_sum(array_map('array_sum', $qualidade));
$offset = 0;
imageconvolution($this->img, $qualidade, $divisao, $offset);
return $this;
}
/**
* retorna saída para tela ou arquivo
* @param String $destino caminho e nome do arquivo a serem criados
* @param Int $qualidade qualidade da imagem no caso de JPEG (0-100)
* @return void
**/
public function grava($destino = '', $qualidade = 100)
{
// dados do arquivo de destino
if ($destino) {
$pathinfo = pathinfo($destino);
$dir_destino = $pathinfo['dirname'];
$extensao_destino = strtolower($pathinfo['extension']);
// valida diretório
if (!is_dir($dir_destino)) {
trigger_error('Diretório de destino inválido ou inexistente', E_USER_ERROR);
}
}
if (!isset($extensao_destino)) {
$extensao_destino = $this->extensao;
}
switch ($extensao_destino) {
case 'jpg':
case 'jpeg':
case 'bmp':
if ($destino) {
imagejpeg($this->img, $destino, $qualidade);
} else {
header("Content-type: image/jpeg");
imagejpeg($this->img, NULL, $qualidade);
imagedestroy($this->img);
}
break;
case 'png':
if ($destino) {
imagepng($this->img, $destino);
} else {
header("Content-type: image/png");
imagepng($this->img);
imagedestroy($this->img);
}
break;
case 'gif':
if ($destino) {
imagegif($this->img, $destino);
} else {
header("Content-type: image/gif");
imagegif($this->img);
imagedestroy($this->img);
}
break;
default:
return false;
break;
}
return $this;
} // fim grava
} // fim da classe
//------------------------------------------------------------------------------
// suporte para a manipulação de arquivos BMP
/*********************************************/
/* Function: ImageCreateFromBMP */
/* Author: DHKold */
/* Contact: admin@dhkold.com */
/* Date: The 15th of June 2005 */
/* Version: 2.0B */
/*********************************************/
function imagecreatefrombmp($filename)
{
//Ouverture du fichier en mode binaire
if (!$f1 = fopen($filename, "rb"))
return FALSE;
//1 : Chargement des ent?tes FICHIER
$FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1, 14));
if ($FILE['file_type'] != 19778)
return FALSE;
//2 : Chargement des ent?tes BMP
$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel' . '/Vcompression/Vsize_bitmap/Vhoriz_resolution' . '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));
$BMP['colors'] = pow(2, $BMP['bits_per_pixel']);
if ($BMP['size_bitmap'] == 0)
$BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;
$BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
$BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
$BMP['decal'] -= floor($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
$BMP['decal'] = 4 - (4 * $BMP['decal']);
if ($BMP['decal'] == 4)
$BMP['decal'] = 0;
//3 : Chargement des couleurs de la palette
$PALETTE = array();
if ($BMP['colors'] < 16777216) {
$PALETTE = unpack('V' . $BMP['colors'], fread($f1, $BMP['colors'] * 4));
}
//4 : Cr?ation de l'image
$IMG = fread($f1, $BMP['size_bitmap']);
$VIDE = chr(0);
$res = imagecreatetruecolor($BMP['width'], $BMP['height']);
$P = 0;
$Y = $BMP['height'] - 1;
while ($Y >= 0) {
$X = 0;
while ($X < $BMP['width']) {
if ($BMP['bits_per_pixel'] == 24)
$COLOR = @unpack("V", substr($IMG, $P, 3) . $VIDE);
elseif ($BMP['bits_per_pixel'] == 16) {
$COLOR = @unpack("n", substr($IMG, $P, 2));
$COLOR[1] = $PALETTE[$COLOR[1] + 1];
} elseif ($BMP['bits_per_pixel'] == 8) {
$COLOR = @unpack("n", $VIDE . substr($IMG, $P, 1));
$COLOR[1] = $PALETTE[$COLOR[1] + 1];
} elseif ($BMP['bits_per_pixel'] == 4) {
$COLOR = @unpack("n", $VIDE . substr($IMG, floor($P), 1));
if (($P * 2) % 2 == 0)
$COLOR[1] = ($COLOR[1] >> 4);
else
$COLOR[1] = ($COLOR[1] & 0x0F);
$COLOR[1] = $PALETTE[$COLOR[1] + 1];
} elseif ($BMP['bits_per_pixel'] == 1) {
$COLOR = @unpack("n", $VIDE . substr($IMG, floor($P), 1));
if (($P * 8) % 8 == 0)
$COLOR[1] = $COLOR[1] >> 7;
elseif (($P * 8) % 8 == 1)
$COLOR[1] = ($COLOR[1] & 0x40) >> 6;
elseif (($P * 8) % 8 == 2)
$COLOR[1] = ($COLOR[1] & 0x20) >> 5;
elseif (($P * 8) % 8 == 3)
$COLOR[1] = ($COLOR[1] & 0x10) >> 4;
elseif (($P * 8) % 8 == 4)
$COLOR[1] = ($COLOR[1] & 0x8) >> 3;
elseif (($P * 8) % 8 == 5)
$COLOR[1] = ($COLOR[1] & 0x4) >> 2;
elseif (($P * 8) % 8 == 6)
$COLOR[1] = ($COLOR[1] & 0x2) >> 1;
elseif (($P * 8) % 8 == 7)
$COLOR[1] = ($COLOR[1] & 0x1);
$COLOR[1] = $PALETTE[$COLOR[1] + 1];
} else
return FALSE;
imagesetpixel($res, $X, $Y, $COLOR[1]);
$X++;
$P += $BMP['bytes_per_pixel'];
}
$Y--;
$P += $BMP['decal'];
}
//Fermeture du fichier
fclose($f1);
return $res;
} // fim function image from BMP
?>