Dark Skyllen 7 #1 Posted August 20, 2010 Programação Gráfica #1 Neste tutorial irei ensiná-los a fazer um programa em Delphi que manipula imagens, um tutorial para quem tem um conhecimento básico em Delphi. O que faremos? Primeiramente, nós faremos um programa que carrega uma imagem e em seguida, manipula ela. Para isso, teremos de entender melhor como funciona uma imagem. As imagens e os filtros Para executarmos o tutorial, primeiramente precisamos entender como as imagens funcionam. As imagens possuem uma coordenada x e y dentro da sua dimensão de largura (width) e altura (height). Essas coordenadas são posicionadas como numa matriz, onde começam em 0,0. Cada ponto da imagem, é composto por 3 cores (RedGreenBlue = RGB) que quando juntas formam uma cor. Podemos ver isso no próprio paint mesmo, veja: Como mostra a imagem acima, para conseguirmos formar a cor selecionada, precisa de uma "mistura" entre as cores RGB, que formariam a cor. Lembrando que 255,255,255 forma o branco, que é a presença de todas as cores e 0,0,0 forma o preto, que é a ausência de todas as cores. Então cada ponto da imagem, terá "guardado" um valor desse, tal como 70,71,80 e etc. Bom, para melhor entendimento, vamos fazer um código para que isso fique mais claro: Abra o Delphi, crie um novo projeto e deixe o formulário desta maneira: Os componentes usados foram: - 1 TImage (Altere a propriedade Stretch para TRUE) - 6 Labels - 1 Button - 1 TOpenDialog (Aba dialogs) Agora, dê duplo clique sobre o botão ou clique no evento onClick do botão; você será redirecionado para a janela de códigos. procedure TForm1.Button1Click(Sender: TObject);beginOpenDialog1.Execute();Image1.Picture.LoadFromFile(OpenDialog1.FileName);end; O que esse código fara? Ele abrirá uma janela de dialogo para selecionar um arquivo, no caso uma imagem BMP, precisa ser BMP senão vai dar erro. Após você selecionar o arquivo, o FileName do diálogo ficará com o caminho do arquivo e com a extensão dele. Então carregamos a imagem para o TImage. Agora, no evento onMouseMove do TImage, coloque o seguinte código: procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Label4.Caption := IntToStr(GetRValue(Image1.Canvas.Pixels[x,y])); Label5.Caption := IntToStr(GetGValue(Image1.Canvas.Pixels[x,y])); Label6.Caption := IntToStr(GetBValue(Image1.Canvas.Pixels[x,y])); end; Então, ao movermos o mouse, ele irá alterar o valores dos labels de acordo com o RGB do pixel que o mouse está. Percebam, que ali emcima: X, Y: Integer); o delphi passa de parâmetro pra essa nossa função onMouseMove a posição X e Y do mouse na imagem, tornando assim mais fácil e prático o código. Agora, apertem F9 e testem. Bom, agora vamos transformar a imagem em escala de cinza? Coloque um novo botão no formulário, e mude o caption dele para Cinza. Também coloque uma ProgressBar (aba win32). No onClick deste botão, coloque o seguinte código: procedure TForm1.Button2Click(Sender: TObject); var i, j, r, g, b, cor: integer; begin ProgressBar1.Position := 0; ProgressBar1.Max := Image1.Picture.Width; for i := 0 to Image1.Picture.Width-1 do begin for j := 0 to Image1.Picture.Height-1 do begin r := GetRValue(Image1.Canvas.Pixels[i,j]); g := GetGValue(Image1.Canvas.Pixels[i,j]); b := GetBValue(Image1.Canvas.Pixels[i,j]); cor := (r+g+ div 3; Image1.Canvas.Pixels[i,j] := RGB(cor,cor,cor); end; ProgressBar1.Position := i; end; end; Bom, primeiro vamos entender a parte da imagem. Para a imagem ficar em escala de cinza, é necessário que o RGB fique em uma média entre as 3 CORES de RGB. Ou seja, o RGB precisa ser igual para o pixel. Pode ver que ao passar o mouse emcima, as cores do RGB são todas iguais no pixel. Então fizemos um for, para varrer a imagem inteira pegando o RGB dela e depois armazenando em uma variável (cor) a média das 3 cores. Depois colocamos essa média no pixel. Também adicionamos uma progressbar que dará mais conforto ao usuário para ver aonde está o progresso. Na verdade o que fizemos foi fazer com que a progressBar tenha o tamanho máximo igual ao tamanho da largura da imagem. Assim, a cada vez que a variável I for incrementada pelo loop, a progressbar receberá o i. Esse será o resultado: Bom pessoal, nessa primeira parte é só! Espero que tenham gostado e aguardem a #2, que trará muitas coisas interessantes! Abraços, Dark Skyllen Share this post Link to post Share on other sites
smeagoulh 0 #2 Posted August 21, 2010 Boa introdução! Uma vez fiz uma biblioteca para brincar com efeitos especiais, fazendo um trabalho simples com cada pixel, como você fez aqui. Extraindo o Red, Green e Blue de cada cor, é possivel fazer tudo, do mais básico (efeitos de blur, contraste, brilho, tonalização) ao mais complicado, como efeitos do photoshop.. O problema é que trabalhar encima do Canvas.Pixels é MUITO LENTO, porque a cada leitura/escrita de um pixel, é feito um processo muito longo pela API do windows... O ideal para ter mais velocidade é usar o ScanLine[x];, oande ele lê diretamente a memória aonde estão os pixels. Esse trabalho é um pouco mais complicado, e precisa do entendimento básico de ponteiros. Procure no google como usar que logo acha, ajuda muito mesmo, fiz um efeito de blur que se aplicava instantaneamente! Aproveitando o método do post, vou dar uma dica também para efeito de contraste. Aonde está r := GetRValue(Image1.Canvas.Pixels[i,j]); g := GetGValue(Image1.Canvas.Pixels[i,j]); b := GetBValue(Image1.Canvas.Pixels[i,j]); cor := (r+g+ div 3; Digite o seguinte código: cor := Image1.Canvas.Pixels[i,j]; r := GetRValue(cor); g := GetGValue(cor); b := GetBValue(cor); // Tratamento do contraste da tonalidade VERMELHA. if (r >= 128) then begin if ((r+2) < 255) then r := r + 2 else r := 255; end else if (r <= 127) then begin if ((r-2) > 0) then r := r - 2 else r := 0; end // Tratamento do contraste da tonalidade VERDE. if (g >= 128) then begin if ((g+2) < 255) then g := g + 2 else g := 255; end else if (g <= 127) then begin if ((g-2) > 0) then g := g - 2 else g := 0; end // Tratamento do contraste da tonalidade AZUL. if (b >= 128) then begin if ((b+2) < 255) then b := b + 2 else b := 255; end else if (b <= 127) then begin if ((b-2) > 0) then b := b - 2 else b := 0; end; [color=black]Image1.Canvas.Pixels[i,j] := RGB(r,g,;[/color] Ficou comprido porque é repetitivo e não usei nenhuma function ou loop para fazer o trabalho, mas o código ficou fácil de se entender dessa forma. Evite fazer a leitura do Pixels[i,j] muitas vezes sem precisar, isso deixa o código muito lento.. jogue o valor do pixel em uma variável que fica bem mais rapido e facil! Peço desculpas caso haja algum erro no código; não estou com o delphi instalado e não posso checar, mas seguindo a lógica do código da pra entender como fazer. Share this post Link to post Share on other sites
Masterious 0 #3 Posted August 24, 2010 Canvas é um processo chato, a uns tempos eu fiz um gerador de classe de canvas.. onde eu passava meus parametros ele me retornava meus views.. isso me ajudava muito..mas para quem esta aprendendo ajuda muito ! =D Share this post Link to post Share on other sites
godmasterlord 0 #4 Posted August 12, 2011 tem como eu carregar uma imagem e salvar em um bd? exemplo: pra quando acessar a ficha de uma pessoa no programa, aparecer a foto dela ao lado Share this post Link to post Share on other sites