TImage - Colocar ponto colorido no clique do mouse
Pessoal...
Tenho um componente TImage aonde eu vou clicar com o mouse sobre a imagem que se abrir (isso em vários pontos da imagem) e eu gostaria que a cada clique do mouse fosse colocado um ponto vermelho (pode ser qualquer cor).
Eu tentei assim:
Mas também não aconteceu nada.
Como eu faço isso?
Agradeço a ajuda de todos.
Tenho um componente TImage aonde eu vou clicar com o mouse sobre a imagem que se abrir (isso em vários pontos da imagem) e eu gostaria que a cada clique do mouse fosse colocado um ponto vermelho (pode ser qualquer cor).
Eu tentei assim:
Image.Picture.Bitmap.Canvas.Pen.Width := 1000; Image.Picture.Bitmap.Canvas.Pixels[Pt.X,Pt.Y] := clRed;
Mas também não aconteceu nada.
Como eu faço isso?
Agradeço a ajuda de todos.
Marcos.gandin
Curtidas 0
Respostas
Vitor Alcantara
20/11/2007
Coloque no evento MouseMove da imagem.
Eu acho que do jeito que estava você pegava o valor do ponteiro em relação ao form e não em relação a imagem.
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in Shift then begin Image1.Picture.Bitmap.Canvas.Pen.Width := 10000; Image1.Picture.Bitmap.Canvas.Pixels[X ,Y ] := clRed; end; end;
Eu acho que do jeito que estava você pegava o valor do ponteiro em relação ao form e não em relação a imagem.
GOSTEI 0
Vitor Alcantara
20/11/2007
Nos testes em que fiz aqui me parece que a linha ´[b:b7ce98774b]Image1.Picture.Bitmap.Canvas.Pen.Width := 10000[/b:b7ce98774b]´ não faz diferença alguma.
GOSTEI 0
Marcos.gandin
20/11/2007
Vitor
A linha [b:90c3782495]´Image1.Picture.Bitmap.Canvas.Pen.Width := 10000´[/b:90c3782495] era somente para aumentar o tamanho da caneta, mas eu também acho que não faz nenhuma diferença.
Obrigado por ajudar...vou testar e depois aviso o resultado.
Flw
A linha [b:90c3782495]´Image1.Picture.Bitmap.Canvas.Pen.Width := 10000´[/b:90c3782495] era somente para aumentar o tamanho da caneta, mas eu também acho que não faz nenhuma diferença.
Obrigado por ajudar...vou testar e depois aviso o resultado.
Flw
GOSTEI 0
Marcos.gandin
20/11/2007
Vitor...
Testei aqui e não aconteceu nada.
Pra você funcionou?
Testei aqui e não aconteceu nada.
Pra você funcionou?
GOSTEI 0
Marcos.gandin
20/11/2007
A única coisa que aconteceu foi eu deixar clicado o botão esquerdo do mouse e ir arrastando ele sobre a figura, aí foi pintando de vermelho, mas mesmo assim, não foi na posição que o ponteiro do mouse estava.
O que eu preciso é somente dar um clique na figura e deixar marcado um ponto, e esse ponto deveria ser bem visivel.
O que eu preciso é somente dar um clique na figura e deixar marcado um ponto, e esse ponto deveria ser bem visivel.
GOSTEI 0
Vitor Alcantara
20/11/2007
Tenta isso no evento MouseDown;
Dessa forma ele cria um circulo onde você clicou na imagem.
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then begin Image1.Picture.Bitmap.Canvas.Brush.Color := clred; Image1.Picture.Bitmap.Canvas.Brush.Style := bsSolid; Image1.Picture.Bitmap.Canvas.Ellipse(x,y,x+10,y+10); end; end;
Dessa forma ele cria um circulo onde você clicou na imagem.
GOSTEI 0
Vitor Alcantara
20/11/2007
So complementando a idéia esse exemplo pode se aplicar perfeitamente para se desenhar na imagem (como um Primo pobre (bem pobre mesmo) do Paint por exemplo).
No evento MouseMove:
Enquanto estiver com o mouse precionado ele vai pintando a imagem.
No evento MouseMove:
if ssLeft in Shift then begin Image1.Picture.Bitmap.Canvas.Brush.Color := clBlack; Image1.Picture.Bitmap.Canvas.Brush.Style := bsSolid; Image1.Picture.Bitmap.Canvas.Pen.Style := psClear; Image1.Picture.Bitmap.Canvas.Ellipse (x,y,x+10,y+10); end;
Enquanto estiver com o mouse precionado ele vai pintando a imagem.
GOSTEI 0
Vitor Alcantara
20/11/2007
Quanto aos pontos não estarem na posição que você indicou, talvez seja por que sua tImagem esteja com a propriedade [b:49af5e7f7e]Strench[/b:49af5e7f7e] setada para [b:49af5e7f7e]true[/b:49af5e7f7e].
GOSTEI 0
Marcos.gandin
20/11/2007
Vitor...
Agora os pontos ficaram maiores, mas a posição continua não sendo a mesma do ponteiro do mouse.
Verifiquei a propriedade Stretch ela está false.
Agora os pontos ficaram maiores, mas a posição continua não sendo a mesma do ponteiro do mouse.
Verifiquei a propriedade Stretch ela está false.
GOSTEI 0
Marcos.gandin
20/11/2007
Tentei fazer assim:
Mas os pontos ainda não estão nos lugares corretos...
procedure TfrmImagem.ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var pt: TPoint; begin GetCursorPos(pt); pt := Image.ScreenToClient(pt); if Button = mbLeft then begin Image.Picture.Bitmap.Canvas.Brush.Color := clBlue; Image.Picture.Bitmap.Canvas.Brush.Style := bsSolid; Image.Picture.Bitmap.Canvas.Ellipse(pt.X,pt.Y,pt.X+5,pt.Y+5); end; end;
Mas os pontos ainda não estão nos lugares corretos...
GOSTEI 0
Vitor Alcantara
20/11/2007
Estranho isso, testei do jeito que você postou por último e do outro jeito e ficou certo, a bolinha que cria sai exatamente na ponto da setinha do mouse, etedendo que ele começa dali da ponta do mouse caso você queira colocar a ponta do mouse exatamente no centro da bolinha dai você teria que diminuir o tamanho pra esquerda (x - tamanho pro lado) e do tamanho pra cima (y - tamanho pra cima), nos parametros left e top.
ex:
Image1.Picture.Bitmap.Canvas.Ellipse(pt.X - 2,pt.Y-2,pt.X+2,pt.Y+2);
No mais não sei o que pode estar errado.
ex:
Image1.Picture.Bitmap.Canvas.Ellipse(pt.X - 2,pt.Y-2,pt.X+2,pt.Y+2);
No mais não sei o que pode estar errado.
GOSTEI 0
Marcos.gandin
20/11/2007
Você pode me dizer exatamente o que está utilizando pra testar?
Ou seja, você criou um form novo, colocou um componente TImage, você carrega uma imagem no componente utilizando um TOpenPictureDialog, e coloca o código que eu postei aí no evento OnMouseDown do componente TImagem ???
É isso?
Ou seja, você criou um form novo, colocou um componente TImage, você carrega uma imagem no componente utilizando um TOpenPictureDialog, e coloca o código que eu postei aí no evento OnMouseDown do componente TImagem ???
É isso?
GOSTEI 0
Marcos.gandin
20/11/2007
Você poderia me enviar esse projeto que você fez pra que eu dê uma olhada, por favor?
Poderia me enviar para o e-mail:
marcos.gandin@hotmail.com
Flw
Poderia me enviar para o e-mail:
marcos.gandin@hotmail.com
Flw
GOSTEI 0
Vitor Alcantara
20/11/2007
Olha ai o dfm
Olha ai o Pas
object Form1: TForm1 Left = 0 Top = 0 AutoSize = True Caption = ´Form1´ ClientHeight = 511 ClientWidth = 708 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = ´Tahoma´ Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Image1: TImage Left = 0 Top = 0 Width = 708 Height = 511 AutoSize = True OnMouseDown = Image1MouseDown end object Button1: TButton Left = 208 Top = 32 Width = 75 Height = 25 Caption = ´Button1´ TabOrder = 0 OnClick = Button1Click end object OpenPictureDialog1: TOpenPictureDialog Left = 344 Top = 256 end end
Olha ai o Pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, jpeg, ExtDlgs, StdCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
OpenPictureDialog1: TOpenPictureDialog;
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
Begin
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName );
End;
end;
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
Image1.Picture.Bitmap.Canvas.Brush.Color := clBlue;
Image1.Picture.Bitmap.Canvas.Brush.Style := bsSolid;
Image1.Picture.Bitmap.Canvas.Ellipse(X-2,Y-2,X+2,Y+2);
end;
end;
end.GOSTEI 0
Marcos.gandin
20/11/2007
Vitor...
Consegui acertar o meu projeto.
O que eu estava fazendo de errado não tinha nada a ver com o código, mas sim com a propriedade [b:d5780290c6]Center[/b:d5780290c6] que eu tinha setado como [b:d5780290c6]True[/b:d5780290c6] para que a imagem que fosse aberta, sempre se posicionasse no centro do componente.
Não sei se isso teria concerto...mas por hora está funcionando.
Valeu pela ajuda.
Obrigado mesmo.
Abraço...
Consegui acertar o meu projeto.
O que eu estava fazendo de errado não tinha nada a ver com o código, mas sim com a propriedade [b:d5780290c6]Center[/b:d5780290c6] que eu tinha setado como [b:d5780290c6]True[/b:d5780290c6] para que a imagem que fosse aberta, sempre se posicionasse no centro do componente.
Não sei se isso teria concerto...mas por hora está funcionando.
Valeu pela ajuda.
Obrigado mesmo.
Abraço...
GOSTEI 0
Micheus
20/11/2007
[quote:fd2a771bf4=´Vitor Araujo Alcantara´]Coloque no evento MouseMove da imagem.
Eu acho que do jeito que estava você pegava o valor do ponteiro em relação ao form e não em relação a imagem.[/quote:fd2a771bf4]
[b:fd2a771bf4]marcos.gandin[/b:fd2a771bf4], o fato de Width=10000 não estar fazendo qualquer diferença neste código, deve-se a o fato de que vc não está utilizando a caneta para desenhar o ponto. Voce está, na verdade apenas mudando sua espessura, mas manipula o pixels, ou seja, apenas 1 ponto!
[b:fd2a771bf4]1[/b:fd2a771bf4]) Supondo que a propriedade Center estará setada antes do uso, inicialmente, vc deve calcular o offset (deslocamento) da imagem dentro do TImage ao carregar o bitmap para o TImage, já que este cálculo só precisaria ser realizado neste momento.
Também aproveita para definir espessura de caneta e cor da mesma (apesar que isto pode ser feito a qualquer momento).
Como eu não tenho um procedimento para carga da imagem, eu adicionei uma em design-time e no evento OnShow do form fiz as inicializações:
Observações: As variáveis XOffiset e YOffset foram declaras na cláusula privare do Form1
[b:fd2a771bf4]2[/b:fd2a771bf4]) no evento OnMouseDown do TImage, vc pode utilizar a propriedade Tag para sinalizar quando o componente estará ou não no modo edição. Neste momento, também posicionamos a caneta:
[b:fd2a771bf4]3[/b:fd2a771bf4]) Ao mover o mouse (evento OnMouseMove), vc verifica se a imagem está no modo edição, caso esteja vc chama o método LineTo que fará uso da caneta para desenhar na imagem a partir da última posição da caneta, neste caso aquela que deixamos ao chamar MoveTo anteriormente.
[b:fd2a771bf4]4[/b:fd2a771bf4]) Ao ser liverado o botão do mouse (evento OnMouseUp), vc verifica se estava no modo edição e, caso esteja, verifica ainda se por acaso o mouse foi apenas pressionado e solto, caracterizando apenas um clique com a intensão de marcar 1 ponto apenas. Caso isto ocorra, forçamos o desenho do ponto.
Este procedimento deve-se ao fato de que não havendo movimento do mouse, não há o evento OnMouseMove e então, ao tentar marcar um ponto não conseguiriamos sem este artifícil.
Teste ai, qualquer coisa...
Abraços
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in Shift then begin Image1.Picture.Bitmap.Canvas.Pen.Width := 10000; Image1.Picture.Bitmap.Canvas.Pixels[X ,Y ] := clRed; end; end;
Eu acho que do jeito que estava você pegava o valor do ponteiro em relação ao form e não em relação a imagem.[/quote:fd2a771bf4]
A linha [b:fd2a771bf4]´Image1.Picture.Bitmap.Canvas.Pen.Width := 10000´[/b:fd2a771bf4] era somente para aumentar o tamanho da caneta, mas eu também acho que não faz nenhuma diferença.
[b:fd2a771bf4]marcos.gandin[/b:fd2a771bf4], o fato de Width=10000 não estar fazendo qualquer diferença neste código, deve-se a o fato de que vc não está utilizando a caneta para desenhar o ponto. Voce está, na verdade apenas mudando sua espessura, mas manipula o pixels, ou seja, apenas 1 ponto!
O que eu estava fazendo de errado não tinha nada a ver com o código, mas sim com a propriedade [b:fd2a771bf4]Center[/b:fd2a771bf4] que eu tinha setado como [b:fd2a771bf4]True[/b:fd2a771bf4] para que a imagem que fosse aberta, sempre se posicionasse no centro do componente.
Não sei se isso teria concerto...mas por hora está funcionando.
A questão de vc ter habilitado a propriedade [i:fd2a771bf4]Center[/i:fd2a771bf4], tem como contornar facilmente. Mas eu acho que seria também interessante, vc realmente utilizar a caneta ao invés do método alternativo, com Ellipse. Veja o exemplo que vou colocar abaixo.[b:fd2a771bf4]1[/b:fd2a771bf4]) Supondo que a propriedade Center estará setada antes do uso, inicialmente, vc deve calcular o offset (deslocamento) da imagem dentro do TImage ao carregar o bitmap para o TImage, já que este cálculo só precisaria ser realizado neste momento.
Também aproveita para definir espessura de caneta e cor da mesma (apesar que isto pode ser feito a qualquer momento).
Como eu não tenho um procedimento para carga da imagem, eu adicionei uma em design-time e no evento OnShow do form fiz as inicializações:
procedure TForm1.FormShow(Sender: TObject); begin if Image2.Center then begin XOffSet := (Image2.Width -Image2.Picture.Width) div 2; YOffset := (Image2.Height -Image2.Picture.Height) div 2; end else begin XOffSet := 0; YOffset := 0; end; Image2.Picture.Bitmap.Canvas.Pen.Width := 10; Image2.Picture.Bitmap.Canvas.Pen.Color := clRed; end;
[b:fd2a771bf4]2[/b:fd2a771bf4]) no evento OnMouseDown do TImage, vc pode utilizar a propriedade Tag para sinalizar quando o componente estará ou não no modo edição. Neste momento, também posicionamos a caneta:
procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // botão mouse pressionado - vamos pintar... // aqui vc pode testar ainda qual o botão pressionado, para habilitar conforme o caso Image2.Tag := 1; // Posiconamos a caneta onde clicamos Image2.Picture.Bitmap.Canvas.MoveTo(X -XOffSet, Y -YOffSet); end;
[b:fd2a771bf4]3[/b:fd2a771bf4]) Ao mover o mouse (evento OnMouseMove), vc verifica se a imagem está no modo edição, caso esteja vc chama o método LineTo que fará uso da caneta para desenhar na imagem a partir da última posição da caneta, neste caso aquela que deixamos ao chamar MoveTo anteriormente.
procedure TForm1.Image2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Image2.Tag = 1 then // se vamos pintar... Image2.Picture.Bitmap.Canvas.LineTo(X -XOffSet, Y -YOffSet); end;
[b:fd2a771bf4]4[/b:fd2a771bf4]) Ao ser liverado o botão do mouse (evento OnMouseUp), vc verifica se estava no modo edição e, caso esteja, verifica ainda se por acaso o mouse foi apenas pressionado e solto, caracterizando apenas um clique com a intensão de marcar 1 ponto apenas. Caso isto ocorra, forçamos o desenho do ponto.
Este procedimento deve-se ao fato de que não havendo movimento do mouse, não há o evento OnMouseMove e então, ao tentar marcar um ponto não conseguiriamos sem este artifícil.
procedure TForm1.Image2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // caso seja apenas clicado e solto o botão, sem o arrasto, então // forçamos o desenho de um ponto, chamando moveto na mesma posição if Image2.Tag = 1 then // se estavamos pintando... with Image2.Picture.Bitmap.Canvas do if ((X -XOffSet) = PenPos.x) and ((Y -YOffSet) = PenPos.Y) then LineTo(X -XOffSet, Y -YOffSet); Image2.Tag := 0; end;
Teste ai, qualquer coisa...
Abraços
GOSTEI 0
Jeferson Machia
20/11/2007
Olá amigo. Sei que já é antigo e desculpe por reabrir, mas estou com algumas dúvidas e acredito que ficaria mais completo se conseguir responder. É o seguinte, como eu faria para apagar a bola que marquei, tipo e se eu marcar umas cinco, mas ai quero retirar uma e deixar apenas 4 bolas na imagem. Como eu poderia fazer isso? Seria subtrair o ponto de x e y ? Para gravar essas posições em um banco de dados seria somente gravar o x e y e depois carregar quando eu chamar o cliente no banco de dados os valores de x e y vem? Outra duvida seria, se x e y guarda todos os valores do pixel, se eu tiver cinco bolas, ele guardo a posição destas 5 somente em um x e y ? Obrigado se puder ajudar. abraço e parabéns.
GOSTEI 0