Introdução
Já há algum tempo, não escrevo, o ColdFusion 8 foi lançado, então escolhi a maior novidade (IMHO) desta versão, que é a criação/edição/manipulação de imagens online, o mais apropriado seria uma abordagem mais ampla e resumida do assunto ColdFusion 8, mas irá achar o assunto bem interessante.
Não vou me aprofundar em definir e muito menos descrever as funções, devido a grande quantidade de funções (50)para tratamento de imagens agregadas nesta versão CF, vou exibir um cfc comentado e simular várias execuções, aproveitem.
Pré-requisito
ColdFusion 8 (download)
Conceito
Vou trabalhar com uma nova tag, a CFIMAGE, com apenas uma action (writeToBrowser), que simplesmente converte a imagem da memória para arquivo, escreve em html a tag IMG apontando para o caminho da imagem gerada na conversão.
Os demais processos embutidos no CFC trabalharão com as funções:
- IsImage
- IsImageFile
- ImageRead
- imageNew
- ImageCopy
- ImageFlip
- ImageCrop
- ImagePaste
- ImageSetDrawingTransparency
- ImageSetBackgroundColor
- ImageShear
- ImageResize
- ImageSetDrawingColor
- ImageDrawLine
- ImageSetAntialiasing
- ImageDrawRect
- ImageDrawText
- ImageBlur
- ImageDrawQuadraticCurve
A partir das funções CFML 8 crio então os métodos para manipulações específicas, de forma a facilitar a utilização e minimizar os possíveis erros, são eles:
- ImageBin
- ImageReflection
- ImageGradient
- Text2Image
- ImageShadow
- ImageRounded
O componente
<cfcomponent> <!--- método testa o tipo da variável, que sempre deve ser um caminho de imagem ou uma variável do tipo imagem ---> <cffunction name="ImageBin" returntype="any"> <!--- caminho da imagem ou variável do tipo imagem ---> <cfargument name="image" type="any" required="yes" > <!--- método util apenas quando criamos imagens dantro deste método, largura da imagem ---> <cfargument name="width" type="numeric" required="no" default="150" > <!--- método util apenas quando criamos imagens dantro deste método, altura da imagem ---> <cfargument name="height" type="numeric" required="no" default="50" > <!--- método util apenas quando criamos imagens dantro deste método, dor de fundo da imagem ---> <cfargument name="backgroundColor" type="string" required="no" default="##FFFFFF" > <cfscript> //Objeto não é do tipo imagem if(NOT IsImage(Arguments.image)){ //Objeto é um arquivo de imagem if(isImageFile(Arguments.image)){ //lê o arquivo de imagem e retorna o binário da imagem return ImageRead(Arguments.image); } //cria imagem e retorna o binário da imagem return imageNew("", Arguments.width, Arguments.height, "rgb", Arguments.backgroundColor); } //retorna o binário da imagem return Arguments.image; </cfscript> </cffunction> <!--- método usado para criar reflexo da imagem ---> <cffunction name="ImageReflection" returntype="any"> <!--- caminho da imagem ou variável do tipo imagem ---> <cfargument name="image" type="any" required="yes" > <!--- se haverá reflexão ou não ---> <cfargument name="posicao" type="boolean" required="no" default="false" > <!--- inverte direção da reflexão---> <cfargument name="right" type="boolean" required="no" default="true" > <!--- inverte direção do gradiente ---> <cfargument name="gdirection" type="boolean" required="no" default="false" > <!--- cor de fundo da reflexão ---> <cfargument name="backgroundColor" type="string" required="no" default="##FFFFFF" > <cfscript> //carrega variável com binario da imagem var img1 = ImageBin(Arguments.image); //cria uma copia da imagem var Copy = ImageCopy(img1, 0, 0, img1.width, img1.height); //cria imagem de fundo da reflexão var img = ImageNew("", img1.width*2.17, img1.height*2, "rgb", Arguments.backgroundColor); //inicia variavel var x = 0; //inicia variavel var direction = 1.4; //inicia variavel var width = img1.width; //inicia variavel var height = img.height*.7; //modifica posição inicial da imagem caso a rfração seja em cima da imagem if(Not Arguments.right and Arguments.posicao){ direction *=-1; x = img.width - img1.width; } //espelhamento da visão da imagem ImageFlip(Copy, "vertical"); //corte em 85% da altura da imagem ImageCrop(Copy, 0, 0, img1.width, Round(img1.height * .85)); //aplica gradiente na imagem Copy = ImageGradient(Copy,Arguments.gdirection,false,1,100,Arguments.backgroundColor); //uni as imagem original com fundo da reflexão ImagePaste(img,img1,x,0); //aplica transparencia na imagem unida ImageSetDrawingTransparency(img,45); //aplica cor de fundo na imagem unida ImageSetBackgroundColor(Copy,Arguments.backgroundColor); //verifica direção da reflexão if(Arguments.posicao){ //trnasforma imagem ImageShear(Copy,direction,"horizontal", "bicubic"); //redimenciona imagem ImageResize(Copy,"100%","50%","MEDIUMQUALITY",2); //redefine variavel width = img.width; //redefine variavel height = img.height *.71; }else{ //redimenciona imagem ImageResize(Copy,"100%","70%","MEDIUMQUALITY",2); } //uni imagem alterada com a refração ImagePaste(img,Copy, 0,img1.height); //corta imagem no tamanho correto ImageCrop(img, 0,0,width,height); //retorna imagem return img; </cfscript> </cffunction> <!--- método para aplicar gradiente na imagem informada---> <cffunction name="ImageGradient" returntype="any"> <!--- caminho da imagem ou variável do tipo imagem ---> <cfargument name="image" type="any" required="yes" > <!--- direção do gradiente vertical/horizontal ---> <cfargument name="direction" type="boolean" required="no" default="false" > <!--- inicio do gradiente ---> <cfargument name="position" type="boolean" required="no" default="false" > <!--- afastamento do gradiente ---> <cfargument name="limit" type="numeric" required="no" default="1" > <!--- alpha ---> <cfargument name="index" type="numeric" required="no" default="100" > <!--- cor do gradiente ---> <cfargument name="backgroundColor" type="string" required="no" default="##FFFFFF" > <cfscript> //carrega variável com binario da imagem var img = ImageBin(Arguments.image); //limita final do gradiente até o limite percentual informado var h = img.height*Arguments.limit; //inicia variavel var w = img.width; //divide o alpha em linhas de acordo com a altura var i = Arguments.index/h; //inicia variavel var per = 0; //inicia variavel var k = 0; //inicia variavel var j = 0; //verifica a direção do gradiente if(Arguments.direction){ //modifica direção do gradiente h = w*Arguments.limit; //altera divisão i = Arguments.index/h; } // aplica a cor do gradiente ImageSetDrawingColor(img, Arguments.backgroundColor); // para cada linha (das 100) em Arguments.index/h aplica uma transparencia diferente for(;k lte h;k++){ // redefine variavel j = k; //corrige numero dependendo da posição, sutil diferença if(Arguments.position) j = h-k; //calcula percentual de transparencia corrente per = 100 - round(i*j*(1.8*Arguments.limit)); //corrige percentual if(per lt 0) per = 0; //aplica tranparencia ImageSetDrawingTransparency(img, per); //verifica direção do gradiente if(Arguments.direction){ //torna o gradiente visivel começando pela direita ImageDrawLine(img, k, 0, k,img.height); }else{ //torna o gradiente visivel cpomeçando pela esquerda ImageDrawLine(img, 0, k, img.width, k); } } //retorna imagem return img; </cfscript> </cffunction> <!--- método aplica texto em imagem ---> <cffunction name="Text2Image" returntype="any"> <!--- texto ---> <cfargument name="text" type="string" required="no" default="teste" > <!--- caminho da imagem ou variável do tipo imagem ---> <cfargument name="img" type="any" required="no" default="" > <cfargument name="width" type="numeric" required="no" default="150" > <cfargument name="height" type="numeric" required="no" default="50" > <cfargument name="x" type="numeric" required="no" default="10" > <cfargument name="y" type="numeric" required="no" default="25" > <cfargument name="backgroundColor" type="string" required="no" default="##FFFFFF" > <cfargument name="textColor" type="string" required="no" default="##000000" > <cfargument name="font" type="string" required="no" default="Trebuchet MS" > <cfargument name="size" type="numeric" required="no" default="25" > <cfargument name="style" type="string" required="no" default="bold" > <cfargument name="strikethrough" type="boolean" required="no" default="no" > <cfargument name="underline" type="boolean" required="no" default="no" > <cfscript> //carrega variável com binario da imagem var image = ImageBin(Arguments.img,Arguments.width, Arguments.height, Arguments.backgroundColor); //inicia variavel var Styles = StructNew(); // tipo da fonte Styles.font = Arguments.font; // tamanho da fonte Styles.size = Arguments.size; // bold/normal Styles.style = Arguments.style; // uso de strikethrough ou não Styles.strikethrough = Arguments.strikethrough; // underline ou não Styles.underline = Arguments.underline; //prepara imagem para receber o texto ImageSetAntialiasing(image, "ON"); // prepara cor do texto ImageSetDrawingColor(image, Arguments.textColor); // aplica o texto na imagem ImageDrawText(image, Arguments.text, Arguments.x, Arguments.y, Styles); //retorna imagem return image; </cfscript> </cffunction> <cffunction name="ImageShadow" returnType="any"> <!--- caminho da imagem ou variável do tipo imagem ---> <cfargument name="image" type="any" required="true"> <!--- define para que lado a sombra será aplicada ---> <cfargument name="position" type="numeric" required="no" default="1"> <!--- distancia da sombra ---> <cfargument name="off" type="numeric" required="no" default="1.5"> <cfargument name="backgroundColor" type="string" required="no" default="##FFFFFF" > <cfargument name="shadow" type="string" required="no" default="##A0A0A0"> <!--- intensidade do blur---> <cfargument name="blur" type="numeric" required="no" default="10"> <cfscript> var i = 2*Arguments.off; //carrega variável com binario da imagem var img = ImageBin(arguments.image); //inicia variavel var img1 = ""; //verifica direção da sombra if(Arguments.position){ //cria imagem com com dimensões para tornar sombra visivel img1 = ImageBin('',img.width + i,img.height + i,Arguments.backgroundColor); }else{ //cria imagem com com dimensões para tornar sombra visivel img1 = ImageBin('',img.width + (i*2),img.height + (i*2),Arguments.backgroundColor); } //aplica cor da sombra na imagem criada ImageSetDrawingColor(img1,Arguments.shadow); //verifica lado que será aplicada a sombra switch(Arguments.position){ case 1: //cria sombra ImageDrawRect(img1, Arguments.off, Arguments.off, img.width, img.height, "yes"); //aplica blur ImageBlur(img1,Arguments.blur); //uni as imagens ImagePaste(img1,img,0,0); break; case 2: //cria sombra ImageDrawRect(img1, Arguments.off, 0, img.width, img.height, "yes"); //aplica blur ImageBlur(img1,Arguments.blur); //uni as imagens ImagePaste(img1,img,0,Arguments.off); break; case 3: //cria sombra ImageDrawRect(img1, 0, 0, img.width, img.height, "yes"); //aplica blur ImageBlur(img1,Arguments.blur); //uni as imagens ImagePaste(img1,img,Arguments.off,Arguments.off); break; case 4: //cria sombra ImageDrawRect(img1, 0, Arguments.off, img.width, img.height, "yes"); //aplica blur ImageBlur(img1,Arguments.blur); //uni as imagens ImagePaste(img1,img,Arguments.off,0); break; } //retorna imagem return img1; </cfscript> </cffunction> <cffunction name="ImageRounded" returntype="any"> <cfargument name="image" type="any" required="true"> <cfargument name="off" type="numeric" required="no" default="10"> <!--- cor do gradiente ---> <cfargument name="backgroundColor" type="string" required="no" default="##FFFFFF" > <cfscript> //carrega variável com binario da imagem var img = ImageBin(arguments.image); //inicia variavel var i = 0; //grau da curva dos cantos var index = Arguments.off; //aplica cor de fundo ImageSetDrawingColor(img,Arguments.backgroundColor); //prepara imagem ImageSetAntialiasing(img,"ON"); //aplica uma linha curva para grau for(i=0;i lte index;i++){ ImageDrawQuadraticCurve(img,i,0,i/(index/2),i/(index/2),0,i); ImageDrawQuadraticCurve(img,img.width-i,0,img.width-i/(index/2),i/(index/2),img.width,i); ImageDrawQuadraticCurve(img,0,img.height-(index-i),(index-i)/(index/2),img.height-((index-i)/(index/2)),(index-i),img.height); ImageDrawQuadraticCurve(img,img.width,img.height-(index-i),img.width-((index-i)/(index/2)),img.height-((index-i)/(index/2)),img.width-(index-i),img.height); } //retorna imagem return img; </cfscript> </cffunction> </cfcomponent>
Exibindo resultados
O componente é bem variado quanto tipos de transformações, colocarei agora os resultados que imagino sejam possível, mas você pode achar mais alguns.






















[]s
Adobe Certified Professional
Macromedia ColdFusion MX 7 Developer




ShareThis
Muito bom ver você escrevendo novamente Pedro.
Sempre com ótimos textos sobre o universo de CF.
Parabéns!
Danilo Santana
Pois é!
Obrigado veio, estamos ai.
[]s
Pedro Claudio
Caraca, meu! Que legal! ColdFusion é meu mais novo sonho de consumo… hehehe