[Resolvido] Class para manipulação de imagens
Motivado por este tópico, resolvi fazer uma classe simples de manipulação de imagens.
<?php
/**
* @brief Biblioteca para simples manipulação de imagens
* @author Hugo Ferreira da Silva
* @link http://www.hufersil.com.br
* @package manipuladores
*/
/**
* @brief Classe para manipulação de imagens
* @link http://www.hufersil.com.br
* @author Hugo Ferreira da Silva
*
*/
class ImageManipulator {
/**
* Constante para indicar alinhamento superior
* @var string
*/
const TOP = 't';
/**
* Constante para indicar alinhamento centralizado
* @var string
*/
const CENTER = 'c';
/**
* Constante para indicar alinhamento inferior
* @var string
*/
const BOTTOM = 'b';
/**
* Constante para indicar alinhamento à esquerda
* @var string
*/
const LEFT = 'l';
/**
* Constante para indicar alinhamento à direita
* @var string
*/
const RIGHT = 'r';
/**
* Constante para indicar um flip na horizontal
* @var string
*/
const HORIZONTAL = 'horizontal';
/**
* Constante para indicar um flip na vertical
* @var string
*/
const VERTICAL = 'vertical';
/**
* Constante para indicar um flip tanto na horizontal quanto na vertical
* @var string
*/
const BOTH = 'both';
/**
* Caminho da imagem original
* @var string
*/
private $imagePath;
/**
* Objeto de imagem
* @var Resource
*/
private $imageSrc;
/**
* Construtor
*
* @brief Recebe o caminho da imagem a ser tratada
* @param string $imagePath Caminho da imagem a ser tratada
* @author Hugo Ferreira da Silva
*/
public function __construct($imagePath){
$this->setImagePath($imagePath);
}
/**
* @brief Retorna o caminho da imagem original
* @author Hugo Ferreira da Silva
* @return string
*/
public function getImagePath() {
return $this->imagePath;
}
/**
* Altera a imagem
*
* @brief Altera a imagem original e já cria o manipulador para ela
* @param string $imagePath Imagem a ser manipulada
* @throws UnexpectedValueException Caso a imagem não exista ou não seja uma imagem válida
* @author Hugo Ferreira da Silva
* @return void
*/
public function setImagePath($imagePath) {
if(is_file($imagePath)){
$img = @imagecreatefromstring( file_get_contents($imagePath) );
if($img === false) {
throw new UnexpectedValueException('O arquivo "'.$imagePath.'" não é uma imagem válida');
}
list($width, $height) = getimagesize($imagePath);
$info = ord(file_get_contents($imagePath, NULL, NULL, 25, 1));
// se for um png transparente
if($info == 4 || $info == 6){
$dstimage = $this->getNewTransparentImage($width, $height);
} else {
$dstimage = $this->getNewImage($width, $height);
}
imagecopyresampled($dstimage,$img,0,0,0,0, $width,$height,$width,$height);
$this->imageSrc = $dstimage;
} else {
throw new UnexpectedValueException('O arquivo "'.$imagePath.'" não existe');
}
$this->imagePath = $imagePath;
}
/**
* Recupera o manipulador da imagem (resource)
*
* @author Hugo Ferreira da Silva
* @return resource
*/
public function getImageSrc() {
return $this->imageSrc;
}
/**
* Adiciona uma imagem na imagem atual
*
* @param ImageManipulator $image Imagem a ser adicionada
* @param int|string $positionX Posição horizontal da imagem
* @param int|string $positionY Posição vertical da imagem
* @throws InvalidArgumentException Caso a posição vertical ou horizontal seja inválida
* @author Hugo Ferreira da Silva
* @return void
*/
public function addImage(ImageManipulator $image, $positionX = self::RIGHT, $positionY = self::BOTTOM){
list($w, $h) = getimagesize($image->getImagePath());
if(!is_numeric($positionX)){
switch($positionX){
case self::LEFT:
$positionX = 0;
break;
case self::RIGHT;
$positionX = $this->getWidth() - $w;
break;
case self::CENTER;
$positionX = ($this->getWidth() - $w) / 2;
break;
default:
throw new InvalidArgumentException('Valor inválido: ' . $positionX);
}
}
if(!is_numeric($positionY)){
switch($positionY){
case self::TOP:
$positionY = 0;
break;
case self::BOTTOM;
$positionY = $this->getHeight() - $h;
break;
case self::CENTER;
$positionY = ($this->getHeight() - $h) / 2;
break;
default:
throw new InvalidArgumentException('Valor inválido: ' . $positionY);
}
}
imagecopy($this->getImageSrc(), $image->getImageSrc(), $positionX, $positionY, 0, 0, $w, $h);
}
/**
* Faz um flip da imagem
*
* @param string $direction direção do flip
* @param boolean $maintainTransparency Indica se é para manter a transparencia da imagem ou nao
* @throws InvalidArgumentException Caso a direção informada seja inválida
* @author Hugo Ferreira da Silva
* @return void
*/
public function flip($direction, $maintainTransparency = TRUE){
$x = 0;
$y = 0;
$w = $this->getWidth();
$h = $this->getHeight();
$dw = $w;
$dh = $h;
$dx = $x;
$dy = $y;
switch($direction){
case self::HORIZONTAL:
$dx = $w - 1;
$dw = -$w;
break;
case self::VERTICAL:
$dy = $h - 1;
$dh = -$h;
break;
case self::BOTH:
$dx = $w - 1;
$dw = -$w;
$dy = $h - 1;
$dh = -$h;
break;
default:
throw new InvalidArgumentException('Valor invalido: ' . $direction);
}
$dest = $maintainTransparency ?
$this->getNewTransparentImage($this->getWidth(), $this->getHeight()) :
$this->getNewImage($this->getWidth(), $this->getHeight());
imagecopyresampled($dest, $this->getImageSrc(), $x, $y, $dx, $dy, $w, $h, $dw, $dh);
$this->imageSrc = $dest;
}
/**
* Recupera a largura da imagem
*
* @author Hugo Ferreira da Silva
* @return int
*/
public function getWidth(){
return imagesx($this->getImageSrc());
}
/**
* Recupera a altura da imagem
*
* @author Hugo Ferreira da Silva
* @return int
*/
public function getHeight(){
return imagesy($this->getImageSrc());
}
/**
* Altera a cor de fundo da imagem
*
* @param boolean $transparent Indica se é para manter a transparencia da imagem
* @param int $r Indice de vermelho
* @param int $g Indice de verde
* @param int $b Indice de azul
* @author Hugo Ferreira da Silva
* @return void
*/
public function setBackgroundColor($r, $g, $B){
$img = $this->getNewImage($this->getWidth(), $this->getHeight(), $r, $g, $B);
imagecopy($img, $this->getImageSrc(), 0, 0, 0, 0, $this->getWidth(), $this->getHeight());
$this->imageSrc = $img;
}
/**
* Redimensiona uma imagem
*
* @param int $width Largura destino
* @param int $height Altura destino
* @param boolean $resample Indica se vai ser feito um resample ou somente resize
* @param boolean $transparent Indica se é para manter a transparencia da imagem
* @param int $r Indice de vermelho
* @param int $g Indice de verde
* @param int $b Indice de azul
* @author Hugo Ferreira da Silva
* @return void
*/
public function resize($width, $height, $resample = true, $transparent = FALSE, $r = 255, $g = 255, $b = 255){
$img = null;
if($transparent) {
$img = $this->getNewTransparentImage($width, $height);
} else {
$img = $this->getNewImage($width, $height, $r, $g, $B);
}
if($resample){
imagecopyresampled($img, $this->getImageSrc(), 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
} else {
imagecopyresized($img, $this->getImageSrc(), 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
}
$this->imageSrc = $img;
}
public function rotate($angle){
$this->imageSrc = imagerotate($this->getImageSrc(), 360 - $angle, -1);
imagealphablending($this->imageSrc, true);
imagesavealpha($this->imageSrc, true);
}
/**
* Salva a imagem em disco
*
* @param string $path Caminho da nova imagem ou NULL para salvar na imagem original
* @param int $quality Qualidade da nova imagem
* @throws InvalidArgumentException Tipo de imagem nao suportado para salvar
* @author Hugo Ferreira da Silva
* @return void
*/
public function save($path = null, $quality = 90){
if(is_null($path)){
$path = $this->getImagePath();
}
list(,,$type) = getimagesize($this->getImagePath());
switch($type){
case IMAGETYPE_BMP:
case IMAGETYPE_JPEG2000:
case IMAGETYPE_JPEG:
case IMAGETYPE_JPC:
case IMAGETYPE_JP2:
case IMAGETYPE_JPX:
imagejpeg($this->getImageSrc(), $path, $quality);
break;
case IMAGETYPE_GIF:
case IMAGETYPE_ICO:
case IMAGETYPE_WBMP:
imagegif($this->getImageSrc(), $path);
break;
case IMAGETYPE_PNG:
imagepng($this->getImageSrc(), $path, $quality);
break;
default:
throw new InvalidArgumentException('Tipo de imagem nao suportado: '.$type);
}
}
/**
* Envia a imagem para o browser
*
* @param int $quality Qualidade da imagem
* @param boolean $addHeader Indica se o header da imagem deve ser gerado ou nao
* @author Hugo Ferreira da Silva
* @return void
*/
public function output($quality = 90, $addHeader = true){
if($addHeader){
$info = getimagesize($this->getImagePath());
header('Content-Type: ' . $info['mime']);
}
$this->save('', $quality);
}
/**
* Desfaz todas as alterações feitas
*
* @author Hugo Ferreira da Silva
* @return void
*/
public function reset(){
imagedestroy($this->imageSrc);
$this->__construct($this->getImagePath());
}
/**
* Limpa o objeto de imagem interno
*
* @author Hugo Ferreira da Silva
* @return void
*/
public function destroy(){
imagedestroy($this->getImageSrc());
}
/**
* Cria um resource de imagem com a cor de fundo especificada
*
* @param int $width Largura da nova imagem
* @param int $height Altura da nova imagem
* @param int $r Indice de vermelho
* @param int $g Indice de verde
* @param int $b Indice de azul
* @author Hugo Ferreira da Silva
* @return resource
*/
protected function getNewImage($width, $height, $r = 255, $g = 255, $b = 255){
$img = imagecreatetruecolor($width, $height);
$color = imagecolorallocate($img, $r, $g, $B);
imagefilledrectangle($img, 0, 0, $width, $height, $color);
return $img;
}
/**
* Cria um resource de imagem com transparencia
*
* @param int $width Largura da nova imagem
* @param int $height Altura da nova imagem
* @author Hugo Ferreira da Silva
* @return resource
*/
protected function getNewTransparentImage($width, $height){
$img = imagecreatetruecolor($width, $height );
imagealphablending( $img, false );
$transparentColor = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
imagefill( $img, 0, 0, $transparentColor );
imagesavealpha( $img,true );
imagealphablending( $img, true );
return $img;
}
}
Exemplo de uso:
$icon = new ImageManipulator('icon.png');
$img = new ImageManipulator('Hydrangeas.jpg');
$img->resize($img->getWidth()*0.5,$img->getHeight()*0.5);
$img->flip(ImageManipulator::BOTH);
$img->addImage($icon, ImageManipulator::CENTER, ImageManipulator::BOTTOM);
$img->output(90,true);
@braços e fiquem com Deus! :thumbsup:
Discussão (0)
Carregando comentários...