Os procedimentos deste post devem ser precedidos pelos já definidos no post da parte I.
Manipulando os pixels de TLazIntfImage
CurColor_old := SrcIntfImg.Colors[0,0];
for py:=0 to SrcIntfImg.Height-1 do
begin
for px:=0 to SrcIntfImg.Width-1 do
begin
CurColor:=SrcIntfImg.Colors[px,py];
TempIntfImg.Colors[px,py] := CurColor xor TColorToFPColor(clRed);
end;
end;
TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false);
TempBitmap.Handle:=ImgHandle;
TempBitmap.MaskHandle:=Mascara.MaskHandle;
Img1.Picture.Bitmap.Assign(TempBitmap);
Img1.Refresh;
Percorremos (scaneamos) as linhas da imagem de cima para baixo (o ponto 0,0 é o superior esquerdo da imagem). A cada linha escaneada, scaneamos da esquerda para a direita.
No exemplo fizemos uma operação lógica xor sobre cada pixel em relação à cor vermelha. Observe o efeito em seu programa.
Código completo deste procedimento
TempBitmap := TBitmap.Create;
oBmp := TBitmap.Create;
oBmp.PixelFormat:=pf32bit;
oBmp := Img1.Picture.Bitmap;
SrcIntfImg:=TLazIntfImage.Create(0,0);
SrcIntfImg.LoadFromBitmap(oBmp.Handle,oBmp.MaskHandle);
TempIntfImg:=TLazIntfImage.Create(0,0);
TempIntfImg.LoadFromBitmap(oBmp.Handle,oBmp.MaskHandle);
CurColor_old := SrcIntfImg.Colors[0,0];
for py:=0 to SrcIntfImg.Height-1 do
begin
for px:=0 to SrcIntfImg.Width-1 do
begin
CurColor:=SrcIntfImg.Colors[px,py];
TempIntfImg.Colors[px,py] := CurColor xorTColorToFPColor(clRed);
end;
end;
TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false);
TempBitmap.Handle:=ImgHandle;
TempBitmap.MaskHandle:=ImgMaskHandle;
Img1.Picture.Bitmap.Assign(TempBitmap);
Img1.Refresh;
Programação com Scripts para Web
Blog da Rede Blogazine
Conteúdos com Pesquisa e Revisão
sexta-feira, 4 de maio de 2012
quinta-feira, 3 de maio de 2012
Lazarus Pascal - TLazIntfImage - Manipulando Bitmaps - I
No Lazarus uma classe especialmente concebida manipula o mapa de pixels:
TLazIntfImage
Isto ocorre porque a classe TBitmap não manipula, incompreensivelmente, pixels.
Carregando uma imagem
Um objeto desta classe não carrega por suas próprias forças uma imagem. É preciso utilizar a classe TBitmap como auxiliar.
Declaração de variáveis
Escreva o seguinte bloco de declaração de variáveis:
var
x, y: Integer;
px, py: Integer;
oBmp: TBitmap;
ImgHandle,ImgMaskHandle, MskHandle: HBitmap;
SrcIntfImg, TempIntfImg: TLazIntfImage;
Carrendo os bitmaps para serem manipulados
oBmp := TBitmap.Create;
oBmp.PixelFormat:=pf32bit;
oBmp := Img1.Picture.Bitmap;
O formato de armazenamento de pixels deverá ser de 32 bits, para conservar a melhor qualidade possível do bitmap (pf32bit) . Um controle Image (Img1) será usado como buffer dos resultados intermediários das alterações que vamos fazer. É bem melhor que manipular as poderosas streams, pois dão apenas um terço de suas dores de cabeça.
O importante aqui é que na terceira instrução oBmp contém o Bitmap (mapa de bits) da imagem que está no controle Image. Em algum lugar este controle foi carregado com um Bitmap (tem que ser um bitmap de arquivo bmp ou de um JPG convertido para bitmap).
Carregando um bitmap com um arquivo BMP
oBmp.LoadFromFile('C:\ _____ .bmp');
Mas o que acontece frequentemente é que carregamos a região bitmap a partir de um JPG, menor e mais consagrado como padrão na Internet. Como fazer ?
Carregando um arquivo JPG
Declaramos uma variável do tipo TJPEGImage no bloco var:
oJPG:TJPEGImage;
Executamos as instruções de instanciação e de carregamento de um JPG:
oJPG:=TJPEGImage.Create;
oJPG.LoadFromFile( 'C:\ _____ .jpg' );
Mas agora estamos numa sinuca. O tipo para manipulação de pixels é BMP e não JPG.
Transformando um JPG num BMP
Utilize a seguinte sequência de instruções:
oJPG:=TJPEGImage.Create;
oJPG.LoadFromFile( 'C:\ _____ .jpg' );
oBmp:=TBitmap.Create;
oBmp.Width:=Largura;
oBmp.Height:=Altura;
oBmp.Canvas.StretchDraw(Rect(0,0,oBmp.Width-1,oBmp.Height-1),oJPG);
oJPG.Assign(oBmp);
oJPG.CompressionQuality:=100;
A variável oJPG contém o conteúdo trazido cru do arquivo JPG. Criamos um TBitmap e carregamos o seu canvas (superfície de desenho) com o JPG contido em oJPG. E ainda podemos descarregar a figura num retângulo pré-dimensionado. No caso, descarregamos num retângulo de Altura e Largura conhecidos, e provavelmente proporcionais às medidas originais da figura.
Carregando para a classe TLazIntfImage
Uma vez obtido o bitmap, fica fácil obter uma imagem de pixels manipuláveis TLazIntfImage:
SrcIntfImg:=TLazIntfImage.Create(0,0);
SrcIntfImg.LoadFromBitmap(oBmp.Handle,oBmp.MaskHandle);
ImgHandle e ImgMaskHandle foram declaradas no início deste post como handles HBitmap do sistema operacional. Estes handles apontam para o bitmap carregado..
De agora em diante,o bitmap está em SrcIntfImg em um formato de pixels individuais e manipuláveis..
Vamos declarar mais duas instruções:
TempIntfImg:=TLazIntfImage.Create(0,0);
TempIntfImg.LoadFromBitmap(oBmp.Handle,oBmp.MaskHandle);
TempIntfImg será um rascunho, para não danificarmos a imagem original SrcIntfImg.
No próximo post vamos manipular os pixels.
TLazIntfImage
Isto ocorre porque a classe TBitmap não manipula, incompreensivelmente, pixels.
Carregando uma imagem
Um objeto desta classe não carrega por suas próprias forças uma imagem. É preciso utilizar a classe TBitmap como auxiliar.
Declaração de variáveis
Escreva o seguinte bloco de declaração de variáveis:
var
x, y: Integer;
px, py: Integer;
oBmp: TBitmap;
ImgHandle,ImgMaskHandle, MskHandle: HBitmap;
SrcIntfImg, TempIntfImg: TLazIntfImage;
Carrendo os bitmaps para serem manipulados
oBmp := TBitmap.Create;
oBmp.PixelFormat:=pf32bit;
oBmp := Img1.Picture.Bitmap;
O formato de armazenamento de pixels deverá ser de 32 bits, para conservar a melhor qualidade possível do bitmap (pf32bit) . Um controle Image (Img1) será usado como buffer dos resultados intermediários das alterações que vamos fazer. É bem melhor que manipular as poderosas streams, pois dão apenas um terço de suas dores de cabeça.
O importante aqui é que na terceira instrução oBmp contém o Bitmap (mapa de bits) da imagem que está no controle Image. Em algum lugar este controle foi carregado com um Bitmap (tem que ser um bitmap de arquivo bmp ou de um JPG convertido para bitmap).
Carregando um bitmap com um arquivo BMP
oBmp.LoadFromFile('C:\ _____ .bmp');
Mas o que acontece frequentemente é que carregamos a região bitmap a partir de um JPG, menor e mais consagrado como padrão na Internet. Como fazer ?
Carregando um arquivo JPG
Declaramos uma variável do tipo TJPEGImage no bloco var:
oJPG:TJPEGImage;
Executamos as instruções de instanciação e de carregamento de um JPG:
oJPG:=TJPEGImage.Create;
oJPG.LoadFromFile( 'C:\ _____ .jpg' );
Mas agora estamos numa sinuca. O tipo para manipulação de pixels é BMP e não JPG.
Transformando um JPG num BMP
Utilize a seguinte sequência de instruções:
oJPG:=TJPEGImage.Create;
oJPG.LoadFromFile( 'C:\ _____ .jpg' );
oBmp:=TBitmap.Create;
oBmp.Width:=Largura;
oBmp.Height:=Altura;
oBmp.Canvas.StretchDraw(Rect(0,0,oBmp.Width-1,oBmp.Height-1),oJPG);
oJPG.Assign(oBmp);
oJPG.CompressionQuality:=100;
A variável oJPG contém o conteúdo trazido cru do arquivo JPG. Criamos um TBitmap e carregamos o seu canvas (superfície de desenho) com o JPG contido em oJPG. E ainda podemos descarregar a figura num retângulo pré-dimensionado. No caso, descarregamos num retângulo de Altura e Largura conhecidos, e provavelmente proporcionais às medidas originais da figura.
Carregando para a classe TLazIntfImage
Uma vez obtido o bitmap, fica fácil obter uma imagem de pixels manipuláveis TLazIntfImage:
SrcIntfImg:=TLazIntfImage.Create(0,0);
SrcIntfImg.LoadFromBitmap(oBmp.Handle,oBmp.MaskHandle);
ImgHandle e ImgMaskHandle foram declaradas no início deste post como handles HBitmap do sistema operacional. Estes handles apontam para o bitmap carregado..
De agora em diante,o bitmap está em SrcIntfImg em um formato de pixels individuais e manipuláveis..
Vamos declarar mais duas instruções:
TempIntfImg:=TLazIntfImage.Create(0,0);
TempIntfImg.LoadFromBitmap(oBmp.Handle,oBmp.MaskHandle);
TempIntfImg será um rascunho, para não danificarmos a imagem original SrcIntfImg.
No próximo post vamos manipular os pixels.
sábado, 28 de abril de 2012
Ocorreu um erro. Tente novamente no Youtube
Nos últimos 2 meses, o Youtube está experimentando problemas de carregamento de vídeos, pequenos ou grandes.
A que se devem estes problemas ?
O Youtube se tornou uma nova provedora de TV. Com isto, o espaço publicitário se deslocou para este site. Muitos ganhos estão se dando através dele. Mas o usuário está sendo penalizado. Além de ter que saltar os anúncios, os vídeos estão sendo atrasados por programas de estatísticas e cookies instalados no computador cliente.
Mais um agravante é estabelecido pelos níveis de segurança dos browsers Chrome, Internet Explorer, Firefox e Opera.
Para resolver este problema, "limpamos" os controles de segurança EXAGERADA e manipulação de arquivos temporários de um controle de navegador num pequeno pacote. Para sua segurança, use somente com o Youtube:
http://www.4shared.com/file/uVzb0qH4/Youtube.html?
A segurança, publicidade e estatística chegou na níveis proibitivos na Internet, e nem quem tem 10 Mb de banda larga consegue ver as coisas direito. Anúncios bancários, de sites de venda e outras chatices nos enervam.
CHEGA. Use este programa e seja feliz. Ele não contém spyware, adware nem "chateware".
A que se devem estes problemas ?
O Youtube se tornou uma nova provedora de TV. Com isto, o espaço publicitário se deslocou para este site. Muitos ganhos estão se dando através dele. Mas o usuário está sendo penalizado. Além de ter que saltar os anúncios, os vídeos estão sendo atrasados por programas de estatísticas e cookies instalados no computador cliente.
Mais um agravante é estabelecido pelos níveis de segurança dos browsers Chrome, Internet Explorer, Firefox e Opera.
Para resolver este problema, "limpamos" os controles de segurança EXAGERADA e manipulação de arquivos temporários de um controle de navegador num pequeno pacote. Para sua segurança, use somente com o Youtube:
http://www.4shared.com/file/uVzb0qH4/Youtube.html?
A segurança, publicidade e estatística chegou na níveis proibitivos na Internet, e nem quem tem 10 Mb de banda larga consegue ver as coisas direito. Anúncios bancários, de sites de venda e outras chatices nos enervam.
CHEGA. Use este programa e seja feliz. Ele não contém spyware, adware nem "chateware".
terça-feira, 24 de abril de 2012
DimLeg - Dimensiona e coloca legendas em imagens
No dia a dia de uma agência, produtora de mídia ou agência de serviços Web, o tratamento de fotos, mesmo básico, toma muito tempo.
Para atender às exigências mais básicas, sem adquirir produtos excessivamente caros e complexos, nossa equipe compôs uma especificação com exigências muito sumárias para tratamento de imagens, se concentrando nos padroes básicos BMP e JPG, evitando os "cliques direitos" menus suspensos e a poluição de infinitos comandos que só servem para confundir os iniciantes.
O resultado é um software livre, em constante evolução, a ser baixado pelo link:
Carregando uma imagem
A imagem pode ser carregada:
1 - Pela barra de endereço de imagens:
2 - Pelo botão Colar:
Tome o cuidado de deixar a caixa de percentual em 100 % a cada carregamento (ela estará habilitada após o primeiro carregamento).
Cortando imagens (CROPing)
A área de ferramentas para corte de imagens está no lado direito do aplicativo:
Usem e abusem.
Para atender às exigências mais básicas, sem adquirir produtos excessivamente caros e complexos, nossa equipe compôs uma especificação com exigências muito sumárias para tratamento de imagens, se concentrando nos padroes básicos BMP e JPG, evitando os "cliques direitos" menus suspensos e a poluição de infinitos comandos que só servem para confundir os iniciantes.
O resultado é um software livre, em constante evolução, a ser baixado pelo link:
Carregando uma imagem
A imagem pode ser carregada:
1 - Pela barra de endereço de imagens:
2 - Pelo botão Colar:
Tome o cuidado de deixar a caixa de percentual em 100 % a cada carregamento (ela estará habilitada após o primeiro carregamento).
Cortando imagens (CROPing)
A área de ferramentas para corte de imagens está no lado direito do aplicativo:
Usem e abusem.
sexta-feira, 16 de março de 2012
Configurando CGI no servidor Quick n Easy
A configuração de servidores Web para executar CGIs é um trabalho aborrecido, pois os produtores deste segmento de software se preocupam com tecnologias muito novas, e se esquecem do tão útil, consagrado, eficiente e seguro CGI (se for bem feito, e se estiver atrás de um Firewall bom).
É preciso entrar no software gerenciador e acessar a opção de menu e depois a aba de CGI:
Se não for possível ler os parâmetros, vamos repetí-los aqui:
Extension: exe
Interpreter: C:\Windows\system\cmd.exe /c
Experimente agora executar CGIs.
É preciso entrar no software gerenciador e acessar a opção de menu e depois a aba de CGI:
Se não for possível ler os parâmetros, vamos repetí-los aqui:
Extension: exe
Interpreter: C:\Windows\system\cmd.exe /c
Experimente agora executar CGIs.
Lazarus Pascal - Criando componentes - II
No post anterior ( Lazarus Pascal - Criando componentes - II ) discutimos o protótipo da classe TGeraHtml. Agora falta realmente colocar funcionalidades nesta classe que será um componente.
Vamos criar duas variáveis PRIVADAS (private) que armazenarão o texto de HTML gerado em duas formas:
Estas variáveis são FHTMLDoc (formato de lista de strings) e FHTMLText (uma só string inteiriça). Para seguir o padrão do Lazarus usamos a letra "F" antecedendo os nomes das variáveis privadas.
E na seção Published da classe definimos a propriedade DocumentoHtml com o tipo TStringList, que lê ou devolve o parâmetro FHTMLDoc.
O pacote para o componente
Vamos então criar um pacote para este componente:
É mostrada uma tela de diálogo onde colocamos a unidade do componente (UComponente_GeraHtml.pas) através do botão Add:
Pressione o botão Compile e depois Install (1a. vez) ou Use => Install (2a. vez em diante).
Após o Install, se tudo der certo, o Lazarus vai reiniciar.
Coloque este componente em um formulário, e observe o Object Inspector:
Observe que apenas pela declaração de uma propriedade TStringList (DocumentoHtml) já aparece o botão que aciona o editor de código. No entanto, ele ainda não é operacional pelo fato de necessitar de acréscimos para funcionar.
O construtor da classe
Os métodos e propriedades funcionais aparecem no Object Inspector, mas para que funcionem corretamente, é preciso que o componente tenha um construtor. Deixamos de colocá-lo para mostrar a sua necessidade:
No construtor é preciso declarar a herança do construtor da classe imediatamente superior (TComponent) expresso na variável AOwner de chamada. Repare que no construtor fizemos a inicialização do campo de tipo TStringList, pois isto é necessário para que se consiga invocar o editor de código ao se pressionar o botão "..." ao lado do campo. Recompilamos o pacote e instalamos.
Quando clicamos no botão "...'" aparece o Editor abaixo:
Erros
No entanto, você vai obter erros para acessar este editor e até para gravar algum formulário com este componente incorporado. Apesar da propriedade DocumentoHtml ser do tipo TStringList, vamos optar pelo tipo TStrings e fazer a sua atribuição no construtor por um método acessor considerando sim o tipo como TStringList. Portanto, devemos proceder às seguintes alterações:
Caso a visibilidade desta imagem não o satisfaça, vamos enumerar o que fizemos:
Desta forma, o componente não mais dá o erro de Access violation até para salvar um formulário onde foi colocado este componente.
Vamos criar duas variáveis PRIVADAS (private) que armazenarão o texto de HTML gerado em duas formas:
- A forma de lista de strings;
- A forma de texto inteiro (uma só string);
E na seção Published da classe definimos a propriedade DocumentoHtml com o tipo TStringList, que lê ou devolve o parâmetro FHTMLDoc.
O pacote para o componente
Vamos então criar um pacote para este componente:
É mostrada uma tela de diálogo onde colocamos a unidade do componente (UComponente_GeraHtml.pas) através do botão Add:
Pressione o botão Compile e depois Install (1a. vez) ou Use => Install (2a. vez em diante).
Após o Install, se tudo der certo, o Lazarus vai reiniciar.
Coloque este componente em um formulário, e observe o Object Inspector:
Observe que apenas pela declaração de uma propriedade TStringList (DocumentoHtml) já aparece o botão que aciona o editor de código. No entanto, ele ainda não é operacional pelo fato de necessitar de acréscimos para funcionar.
O construtor da classe
Os métodos e propriedades funcionais aparecem no Object Inspector, mas para que funcionem corretamente, é preciso que o componente tenha um construtor. Deixamos de colocá-lo para mostrar a sua necessidade:
No construtor é preciso declarar a herança do construtor da classe imediatamente superior (TComponent) expresso na variável AOwner de chamada. Repare que no construtor fizemos a inicialização do campo de tipo TStringList, pois isto é necessário para que se consiga invocar o editor de código ao se pressionar o botão "..." ao lado do campo. Recompilamos o pacote e instalamos.
Quando clicamos no botão "...'" aparece o Editor abaixo:
Erros
No entanto, você vai obter erros para acessar este editor e até para gravar algum formulário com este componente incorporado. Apesar da propriedade DocumentoHtml ser do tipo TStringList, vamos optar pelo tipo TStrings e fazer a sua atribuição no construtor por um método acessor considerando sim o tipo como TStringList. Portanto, devemos proceder às seguintes alterações:
Caso a visibilidade desta imagem não o satisfaça, vamos enumerar o que fizemos:
- A variável FHTMLDoc, que armazena o valor da propriedade DocumentoHtml, foi declarada como TStrings;
- Declaramos um método acessor (procedure setHtmlDoc) que envia um valor do tipo TStrings;
- Modificamos o tipo da propriedade DocumentoHtml para TStrings;
- Colocamos o método acessor para ajustar a propriedade DocumentoHtml;
- No construtor, criamos a variável que armazena a propriedadeDocumentoHtml como TStringList, apesar de ela ser do tipo TStrings;
- No método acessor, utilizamos a procedure Assign do tipo TStrings;
Desta forma, o componente não mais dá o erro de Access violation até para salvar um formulário onde foi colocado este componente.
quinta-feira, 15 de março de 2012
Lazarus Pascal - Criando componentes - I
Sem enrolação, vamos explicar detalhadamente a criação de componentes no novo e excelente Lazarus Pascal (0.9.30.2).
Unit
O componente é baseado numa Unit. Como até esta versão do Lazarus não temos uma template de componente, teremos que:
Criar uma nova Unit (File => New Unit) e através do Project Inspector tirá-la do projeto.
Este é o corpo default de uma unit:
Vamos compor uma classe que será INCORPORADA à paleta de componentes do Lazarus para uso posterior. Ela será algo útil como um gerador de códigos HTML. Na maior parte de seus métodos obteremos como resultado (retorno de função) código HTML gerado.
A classe
Os componentes são expressos em forma de classes Pascal que se conectam ao framework do Lazarus para poderem ser incluídos em formulários Lazarus.
O nome de nossa classe será TGeraHtml. Desta forma, seu protótipo dentro de uma Unit Lazarus. Desta forma, o protótipo de nossa classe será:
O nome da classe leva a letra "T" antes do nome para ficar dentro do padrão Lazarus. O componente é uma extensão da classe TComponent (é óbvio). O protótipo de TComponent já carrega consigo uma série de interfaces que o tornam adequado a ser incluído em um formulário.
Procedimento de registro
Para ser incorporado à paleta de componentes do Lazarus, o componente precisa ter um método de registro na paleta, dando a forma final do protótipo de componentes do Lazarus Pascal.
Repare que salvamos a Unit com um nome sugestivo, e que por isto o Lazarus altera seu nome na cláusula Unit.
Este é o protótipo básico do componente.
Unit
O componente é baseado numa Unit. Como até esta versão do Lazarus não temos uma template de componente, teremos que:
Criar uma nova Unit (File => New Unit) e através do Project Inspector tirá-la do projeto.
Este é o corpo default de uma unit:
Vamos compor uma classe que será INCORPORADA à paleta de componentes do Lazarus para uso posterior. Ela será algo útil como um gerador de códigos HTML. Na maior parte de seus métodos obteremos como resultado (retorno de função) código HTML gerado.
A classe
Os componentes são expressos em forma de classes Pascal que se conectam ao framework do Lazarus para poderem ser incluídos em formulários Lazarus.
O nome de nossa classe será TGeraHtml. Desta forma, seu protótipo dentro de uma Unit Lazarus. Desta forma, o protótipo de nossa classe será:
Procedimento de registro
Para ser incorporado à paleta de componentes do Lazarus, o componente precisa ter um método de registro na paleta, dando a forma final do protótipo de componentes do Lazarus Pascal.
Repare que salvamos a Unit com um nome sugestivo, e que por isto o Lazarus altera seu nome na cláusula Unit.
Este é o protótipo básico do componente.
Assinar:
Postagens (Atom)