Ekrandan görüntü alma

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
nightwolfcem
Üye
Mesajlar: 32
Kayıt: 02 Eki 2008 02:55

Ekrandan görüntü alma

Mesaj gönderen nightwolfcem »

Ekrandan görüntü almak için ufak bir bir program hazırladım.programla ekranın istenilen bir alanı seçilip programa aktarılıyor ve çıktısı
alınabiliyor.
bir resim programı, ekranda kopyalanıcak alanı seçerken ,seçilen kısmı belirten bir dörtken çizdiriyor ve ortasındada boyutlarını yazdırıyordu bende aynı şeyi yapmak istedim ama malesef beceremedim.
Aslında dörtgeni çizdirdim.pen modu ile bir önceki çizimide temizleye biliyorum. Ancak yazıyı temizliyemediğim için önceki yazılar ekranda kalıyor.
Bunu nasıl önleyebilirim önerisi olan arkadaşlar yardımcı olursa sevinirim.
merak eden arkadaşlar için programın kaynak kodu aşağıda (jedi components yüklü olmalı )
Screen capture Source.rar
Kullanıcı avatarı
CiTiZEN
Üye
Mesajlar: 1163
Kayıt: 06 Oca 2008 04:15

Re: Ekrandan görüntü alma

Mesaj gönderen CiTiZEN »

Amaç ekranı temizlemekse;bu kod boyutları verilen ekranın tamamını temizleyecektir.

Kod: Tümünü seç

var r:trect;
begin
R:=Rect(0,0,cizimformu.ClientWidth,cizimformu.ClientHeight);
cizimformu.cizimekrani.Canvas.Brush.Color:=clWhite;
cizimformu.cizimekrani.Canvas.FillRect(R);
UWESIS CORPORATION
Lord_Ares
Üye
Mesajlar: 1070
Kayıt: 15 Eki 2006 04:33
Konum: Çorlu

Re: Ekrandan görüntü alma

Mesaj gönderen Lord_Ares »

aşağıdaki kod ile yapabilirsin ayrıca bileşen kullanmana gerekyok. dikkat etmen gerekenler.

1) xkordinat ve ykordinat dedim şey, çekmek istedin yerin başlangıç pozisyonları.
örnek: ekranın sol köşesinden 10 pixel sola demek için xkordinatın değerini 10 yap;
bu xkordinat diye değişken tanımlamana gerek yok direk rakam olarak oraya yazabilirsin
ben anlaşılır olsun diye yazdım.



procedure TForm1.Resim_Yakala;
var
DCDesk : HDC;
ID : DWORD;
str : TMemoryStream;
pencerehandle:HWND;
Resim:TBitmap;
genislik,yukseklik:integer;
xkordinat,ykordinat:integer;
begin
str := TMemoryStream.Create;
Resim := TBitmap.Create;
Resim.Width := resmicekilecekpencerehandle.genislik;
Resim.Height := Oyun_Wnd.oyun_Height;
DCDesk := GetWindowDC(pencerehandle);
BitBlt(Resim.canvas.Handle, 0, 0, pencerehandle.genislik, pencerehandle.yukseklik , DCDesk, xkordinat,ykordinat, SRCCOPY);
ReleaseDC(GetDesktopWindow, DCDesk);
try
Resim.SaveToStream(str);
finally
try
str.Position := 0;
Resim.LoadFromStream(str);
Resim.SaveToFile(Getcurrentdir+'\tesst.bmp');
finally
// burada çektin resim ile yapmak istediklerini yapabilirsin
end;
str.Free;
end;
nightwolfcem
Üye
Mesajlar: 32
Kayıt: 02 Eki 2008 02:55

Re: Ekrandan görüntü alma

Mesaj gönderen nightwolfcem »

Lord_Ares yazdı:aşağıdaki kod ile yapabilirsin ayrıca bileşen kullanmana gerekyok. dikkat etmen gerekenler.
Sağol, ancak benim sorunum kaydetmekte değil . Benim sorunum , kaydedilecek Bölgenin kullanıcı tarafından fare ile seçtirilmesi sırasında.
Şöyle söyliyim. Kullanıcı programda ekran görüntüsü al diyor daha sonra fare ile ekran görüntüsü alınacak kısmı monitörden seçiyor. Bu seçim sırasında seçilen bölge yi belirtmek için dörtgen çiziliyor ve ortasına seçilen alanın en ve boy boyutlarının değerleri yazılıyor. Dörtgeni çizdiriyorum ama yazıyı çizdirirken ekrandan bir önceki yazı silinmiyor.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Ekrandan görüntü alma

Mesaj gönderen mrmarman »

Formuna bir tane TStaticText nesnesi koy. OnMouseMove olayında lokasyonunu mouse'un olduğu yani sağ alt köşeye taşır belirlediğin formatta koordinatı gösterirsin.

Basitçe örneklemek için senin için aşağıdaki kurguyu hazırladım.

Kod: Tümünü seç

var
  xBasX, xBasY : Integer;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if xBasX < 0 then
  begin
    Shape1.Visible        := True;
    StaticText1.Visible   := True;
    StaticText1.Alignment := taRightJustify;
    Application.ProcessMessages;
    Shape1.BringToFront;
    Shape1.Left := X + Image1.Left;
    Shape1.Top  := Y + Image1.Top;
    xBasX := X;
    xBasY := Y;
    Shape1.Width  := 1;
    Shape1.Height := 1;
    StaticText1.Left := Shape1.Left + Shape1.Width;
    StaticText1.Top  := Shape1.Top  + Shape1.Height;
  end;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Caption := Format('X,Y : %d,%d', [X,Y]);
  if Shape1.Visible then begin
    Shape1.Width  := X - xBasX;
    Shape1.Height := Y - xBasY;
    StaticText1.Caption := Format( '%dx%d', [Shape1.Width, Shape1.Height] );
    StaticText1.Left := Shape1.Left + Shape1.Width - 50;
    StaticText1.Top  := Shape1.Top  + Shape1.Height;
  end;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Shape1.Visible      := False;
  StaticText1.Visible := False;
  xBasX := -1;
  xBasY := -1;
end;
Resim
Resim ....Resim
nightwolfcem
Üye
Mesajlar: 32
Kayıt: 02 Eki 2008 02:55

Re: Ekrandan görüntü alma

Mesaj gönderen nightwolfcem »

mrmarman yazdı:Formuna bir tane TStaticText nesnesi koy. OnMouseMove olayında lokasyonunu mouse'un olduğu yani sağ alt köşeye taşır belirlediğin formatta koordinatı gösterirsin.
Çok sağolun zaman ayırdığınız için teşekkürler ancak
Yapmak istediğim ekran görüntüsünü formdaki bir image nesnesine aktarıp ordan seçim yapmak değil.
Direk seçimi desktop üzerinden yapmak .

Kod: Tümünü seç

 dc:=GetWindowDC(GetDesktopWindow);
  setrop2(dc,R2_NOTXORPEN);
with old do
Rectangle(dc,Left,top,right,Bottom);
with new do
Rectangle(dc,Left,top,right,Bottom);
ile dörtgeni tekrarlanmadan çizdirebiliyorum . Ama yazıyı tekrarlamadan çizdirmek için , kalem deki gibi "R2_NOTXORPEN" eski çizimi sildiricek bir fonksiyon bulamadım.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Ekrandan görüntü alma

Mesaj gönderen mrmarman »

anlıyorum.
Eski sayfayı tümüyle temizlemek gerekecek ama siz şöyle yapın. Çerçeve basmadan önce çerçeve kadarlık alanın DC kopyasını alın. Ekrana basacağınız çizgi, yazı, bilgi vs. bu sınırlar içinde olacak şekilde çizin. Sonra eski DC kopyasını ekrana geri basın böylece temizlenmiş olur ve bir sonraki hamleye geçin. Belki de düşünmüşsünüzdür ama belirtmediğiniz için yazma gereği duydum.
Resim
Resim ....Resim
nightwolfcem
Üye
Mesajlar: 32
Kayıt: 02 Eki 2008 02:55

Re: Ekrandan görüntü alma

Mesaj gönderen nightwolfcem »

mrmarman yazdı:anlıyorum.
Eski sayfayı tümüyle temizlemek gerekecek ama siz şöyle yapın. Çerçeve basmadan önce çerçeve kadarlık alanın DC kopyasını alın. Ekrana basacağınız çizgi, yazı, bilgi vs. bu sınırlar içinde olacak şekilde çizin. Sonra eski DC kopyasını ekrana geri basın böylece temizlenmiş olur ve bir sonraki hamleye geçin. Belki de düşünmüşsünüzdür ama belirtmediğiniz için yazma gereği duydum.
Yoğunlukdan yazamadım .Ancak hala aklım karışık. Sizin demek istediğiniz işlem sırası şöylemi acaba
Ekran Görüntüsü Al 'a Tıklandı
Form1 Gizlendi
Fare yakalama başlatıldı(MouseHook)
Eğer Farenin sağ tuşuna basıldıysa Bunu programa bildir
{
Ekranın(DESKTOP) O anki görüntüsünü al(KOPYA)
}
Eğer Fare hareket ediyorsa
{
SEçilen dörtgenin Kordinatlarını belirle(RECT)
RECT lik kadar bir alanı KOPYADA seç Ve Başka bir KOPYADA Dörtgeni ve Yazıyı yaz(KOPYA1)
KOPYA1 i tekrar DESKTOP ' a çizdir.
}
Eğer Sağ Tuş bırakılmışsa
{
Seçilen Kısmı(RECT) KOPYA dan alarak Programdaki resme aktar ve programı tekrar göster
}
Bu şekilde Düşündüm ancak Mousemove olayında pc yi çok zorluycağını düşündüm
Düşündüğüm ve zorlamıycağını tahmin ettiğim bir yol ise seçim boyutunda Transparan bir form üzerinde Çizim yaptırmak ve DEsktop üzerinde
yapılıyormuş gibi göstermekti ancak bu yolda tahminimden fazla bilgisayarı zorluyor. :(
Birde Şöyle birşey var Dediğim programda kopya filan almak yok direk çizim desktop üzerine yapılıyor bundan eminim.
Tamam Çizgiyi çizdirmekte temizlemekte sorun yok ama yazıya gelince takılıyorum...
Ve bir sorum daha var invalidaterect niye desktop da işe yaramıyor. ekranı yenilemek için ne yapmak lazım
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Ekrandan görüntü alma

Mesaj gönderen mrmarman »

Sıralamada sistemden sürekli ekran capture olursa zorlar. Siz aldığınız aynı ekran görüntüsünü MouseMove boyunca kullanacaksınız.

Ekran 1024x768 olduğunu varsayalım.
- Bitmap içinde mouse butonuna basıldığında 1 defalığına bu ekran kopyası tümüyle alınır. X ve Y değerleri yedeklenir.
- MouseMove olayı boyunca X değeri yönü ve Y değerlerinin yönü yedeklenen X ve Y değerine göre hangi tarafa göre olduğu (ARTI) çizeceğin çizginin PEN kalınlığı dikkate alınarak daha genişini Orjinal Bitmap içinden okuyup yapıştırıp (tekrar tekrar ekran okuma yok bunun altını çizelim) en son X-Y koordinatına göre yeni çerçeve çizilir.

bu işlem Mouse tuşu bırakılana kadar sürer. Yani tekl bir kopya ama defaten aynı kopya içindeki cliptrect kadar alıp yapıştırma söz konusu.
Resim
Resim ....Resim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Ekrandan görüntü alma

Mesaj gönderen mrmarman »

Sana bir örnek hazırladım indirip deneyebilirsin.

"Capture" butonuna basınca arka fonu görüyorsun. Oradan seçim yaparken ekranda bir noktalı shape ile blok aldığın alan görünüyorken, aynı zamanda blokladığın alanın büyüklüğü de mouse yanıbaşında sürekli gösteriliyor. Mouse butonundan kaldırdığın anda da Form'daki küçük resim penceresinde seçtiğin alanın bir fotoğrafı beliriyor.

Aslında işlem bir ilüzyondan ibaret. Bazı noktalara nedeni konusunda dikkat çekmek isterim.
1. Ana formumuz capture edilecek ekranda görünmesin diye gizlenmesi gerekiyordu. Bunu formu Hide yaparak değil de ekrandaki konumunu (-) işareti ile 0'ın altında bir bölgeye çekmek daha hızlı sonuç vermektedir.

2. Ekran kopyası alınırken direkt DC işlem yapılabilir ancak ekranda herhangi bir video veya animasyon olması durumunda bunun estetik bozulmasına karşın kullanıcının duyabileceği rahatsızlık nedeniyle form üzerine anlık taşıma yapılıp oradan resim kopyası alınıyor.

3. Dilersen iptal durumu için capture ekranında bir button da koyabilirsin. Uygulama tümüyle etüd amaçlıdır. Detaylar ihtiyaca göre eklenebilir.

4. Form üzerindeki nesnelerin konumları, durumları ve bağlantıları FormCreate ve / veya FormShow eventinde manuel olarak verilmiştir. Böylece varsayılan ayarların ne olduğunun görülebilmesi sağlandı.

Başarılar...
Dosya ekleri
ScreenCapture.rar
Ekrandan mouse ile seçilen kısmın resim kopyasını almak için örnek kod.
(192.19 KiB) 317 kere indirildi
Resim
Resim ....Resim
nightwolfcem
Üye
Mesajlar: 32
Kayıt: 02 Eki 2008 02:55

Re: Ekrandan görüntü alma

Mesaj gönderen nightwolfcem »

mrmarman yazdı:Sana bir örnek hazırladım indirip deneyebilirsin.
Allah razı olsun zaman ayırdığınız için Güzelde olmuş program.ancak ben desktopa çizdirme olayını kafaya taktım :? çünkü elimdeki program arka planda
video da olsa üzerine iz bırakmadan çizdiriyor ve nasıl başarıyor çok merak ediyorum.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Ekrandan görüntü alma

Mesaj gönderen mrmarman »

Elinizdeki program şöyle bir yöntem uyguluyordur; formun AlphaBlend değerini oldukça transparan hale getirecek kadar bir noktada tutup, arkada kalan kısmın görünür halde olması sağlanıyordur ve yine aynı formun üzerinde çizim yaptırıyordur. Sonra da formu kaldırıp arka kısımdan grab işlemini yapıyordur.
Resim
Resim ....Resim
nightwolfcem
Üye
Mesajlar: 32
Kayıt: 02 Eki 2008 02:55

Re: Ekrandan görüntü alma

Mesaj gönderen nightwolfcem »

mrmarman yazdı:Elinizdeki program şöyle bir yöntem uyguluyordur; formun AlphaBlend değerini oldukça transparan hale getirecek kadar bir noktada tutup, arkada kalan kısmın görünür halde olması sağlanıyordur ve yine aynı formun üzerinde çizim yaptırıyordur. Sonra da formu kaldırıp arka kısımdan grab işlemini yapıyordur.
O metodu ben uyguluyorum ancak şöyle bir sorun cıkıyor onu yapınca alpha belend forma uygulandığından cizimde doğal olarak formun canvasına yapıldığından saydam gözüküyor. Onun yerine transparentColor falan denedim ama oda makinayı çok zorladı. :S
Cevapla