Simge durumunda küçültümüş pencerenin ekran görüntüsünü almak

Merhaba, başlıkta belirttiğim gibi simge durumunda küçültülmüş bir pencerenin ekran görüntüsünü almaya çalışıyorum pek çok kaynak araştırdım fakat internette bunun net bir örneğini göremedim elimde nasıl yapacağıma dair bir kaynak var fakat anlamadım yardımcı olursanız sevinirim.

kaynak: python - Getting screenshot via printwindow not redrawing if laptop screen off - Stack Overflow

1 Beğeni

Simge durumunda kucultulmus bir pencerenin goruntusunu alamazsiniz cunku simge durumunda kucultulmus bir pencerenin goruntusu yoktur.

Bulacaginiz butun cozumler pencereyi baska bir duruma getirmek veya cizim kodunu pencerenin baska bir durumda olduguna kandirmak uzere olacaktir. Net bir cevap bulamamanizin sebebi bu.

Evet bunun farkındayım dolambaçlı bir yolda olsa alternatif çözüm arıyorum.

Dolambacli veya dolambacsiz herhangi bir cozumu yok cunku sordugunuz sey imkansiz. Olmayan bir seyi alamazsiniz.

Simge durumundan kurtarıp , görüntüyü alıp tekrar simge durumuna indirmek çözüm olur mu?

Kolay:

RGB matrisine/tensörüne çevir cv ve numpy kullanarak. Sonra ona göre işle.
Belirli koordinatlardaki matrisi de alabilirsin, hatta cv ile değil, pyautogui ile de alırsin(ama cv C++ tabsnlı olduğu için daha hızlı olur).
Pyautogui ile ilgili görüntü kısmını direk bulabilirsin, o yüzden söyledim. Cv ile bunu da kendin yazman gerekir. Ama genel olarak cv daha hızlı çalışır bu konuda bence.

Ama once simge durumundan çıkarman lazım.
HOHOHAHAHOA
olum deli misin, işlemci lan bu, cpu ve oradan gpu ya kopyalayarak gönderdiği görüntü bilgisini döndürmeden nasıl o bilgiyi çeksin.

Senin o dediğin sihir o, büyü.

Dur, ciddi cevap vereyim. Aslında büyük görüntülerin bile hafızadaki yeri, simge durumuna gelmiş halinin hafızadaki yeri gibi saklanabilsin diye çeşitli graf fonksiyonları var. Fakat bunu, bizzat gömülü işlemcinin dili, otomatikmen(yani sen simge durumuna küçülttüğünde) hafızada bekletsin diye mesela yapar bu işlemi. Ama, programlama dilini tasarlayanlar(yani python için, mesela yordayanlar) bunu düşünerek bir fonksiyon geliştirirse pythonda, o zaman olabilir belki. (Ki bunun olması icinde, yordadıkları dilin zaten assembly çalışarak bu söz konusu graf fonksiyonunu üretmiş olmaları ya da assemblyden çevirmiş olmaları gerekir.)

Ama sanmam. Zira graf teorilerini daha cok assembly seviyesinde kullanırlar kod tasarlamada, yüksek seviyeli dillerde bunla uğraşan olmaz. Daha çok optimal bellek kullanımında bunu yaparlar. Yüksek seviyeli diller genelde pratik amaçlar içindir.

O yüzden, büyü olarak kalabilir bu dediğin.

Ya brainfuckerlar uğraşır bu dediğinle ya da büyücüler.

Merhaba, simge durumuna küçültülmüş bir pencerede çizim yapılmaz. Bu nedenle almak istediğiniz pencere görüntüsünde, butonlar, metinler vs olmayacaktır. Bu Windows’un çalışma mekanizması ile alakalı bir durum. Pencereniz ekranda iken bir döngü ile sürekli boyanmaktadır. Size durağan görünse de aslında işlemciden alınan zaman diliminde sürekli tekrar tekrar boyanarak gösterilmektedir. Ama simge durumuna küçültüldüğünde bu tekrar boyama işlemleri durdurulacağından boş bir ekran şeklinde olacaktır. Bundan alacağınız görüntü bir işinize yaramayacaktır.

Bu nedenle size;

Şeklinde bir öneri gelmiş.

Benzer şekilde;

Bir öneri gelmiş.

Yani simge durumunda bir pencerede DC (Device Context) içi boş olacaktır. Aslında boş değil sadece, başlık ve tekrar işletebileceğiniz komut başlık çubuğu kadar çizim bilgisi içerecektir.

Verdiğiniz linki takip edersek;

Bizi bir python koduna gönderiyor.

Yazılan kod eski ve python 2.x uyumlu.

Bunu biraz düzenleyelim:

import win32gui
import win32ui
from ctypes import windll
from PIL import Image

hwnd = win32gui.FindWindow(None, 'Calculator')

left, top, right, bot = win32gui.GetWindowRect(hwnd)
w = right - left
h = bot - top

hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC  = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()

saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)

saveDC.SelectObject(saveBitMap)

result = windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 3)

print (result)

bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)

im = Image.frombuffer(
    'RGB',
    (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
    bmpstr, 'raw', 'BGRX', 0, 1)

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnd, hwndDC)

if result == 1:
    #PrintWindow Succeeded
    im.save("test.png")

Bir hesap makinesi açıyoruz. Simge durumuna getiriyoruz. Sonra yukarıdaki kodu çalıştırıyoruz. Kodu çalıştırdığımızda ekran görütüntüsü alabilirse konsola 1 sayısını yazıyor. Çalıştırdığımız kodun bulunduğu klasörde test.png adında bir görüntü dosyası oluşuyor.

Normalde simge durumuna küçültülmemiş bir pencerede ekran görüntüsü;

Ama biz simge durumuna getirip ekran görüntüsü aldığımızda aşağıdaki gibi bir görüntü oluşur.

Yani simge durumuna getirilmiş bir ekranın DC içeriğini aldığımızda butonları göremeyiz çünkü simge durumunda iken bu butonlar çizilmez.

Yani teorik olarak evet simge durumundaki bir programın ekran görüntüsünü aldık ama pratikte pencere içinde çizilen hiç bir buton olmadığından ekranda bu butonları göremeyiz.

Yani bir windows penceresi simge durumuna küçültüldüğünde çizilmeyeceğinden içi boş olacaktır.

İstisna bir durum var. Bu programı yapan kişi özellikle simge durumunda iken çizilmeye devam etmesini isterse bunu koduna eklemişse ancak simge durumunda iken pencere çizilmeye devam eder.

Drawing a Minimized Window - Win32 apps | Microsoft Learn

Ama hiç bir programcı durduk yere böyle bir şey yapmaz.

Yani normal şartlarda istediğiniz şeyi yapan bir kod yok. Yada yaptığı şey işinize yaramaz.

Var alternatif çözüm var. Yukarıda alıntıladığım iki katılımcının da söylediği gibi, pencereyi simge durumundan çıkarıp, sonra ekran görüntüsü alıp sonra tekrar simge durumuna küçültebilirsiniz.

Burada iki küçük hususa dikkat etmek gerekir. Pencereyi simge durumundan normal pencere haline getirdiğinizin görünmesini istemeyebilirsiniz. Sanki hala simge durumunda ve ekran görüntüsü almış gibi bir algı yaratabilirsiniz.

Nasıl yaparsınız.

  1. Pencere animasyonunu gecici olarak kapatacak bir kod satırı.

  2. Pencereyi transparan olarak ekrana almak (transparency değerini yüksek tutarsanız pencere görünmez olur.)

  3. Ekran görüntüsü almak

  4. Sonra transparan değerini ve anismasyon değerini eski hale getirmek.

Bu aşamalar size bir yanılsama sağlayacaktır. Ekranın açıldığı görülmez çünkü animasyon kapalı, ekran tam açıldığında şeffaf olduğundan siz görmezsiniz ekran resmi alınır ve son olarak her şey eski haline getirilir.

Amacınızı yazmamışsınız, hangi programın simge durumundan ekran görüntüsü almak istiyorsunuz, hangi bilgiler gerekiyor, ne yapmaya çalışıyorsunuz bu konularda açıklama yaparsanız farklı yaklaşımlar da sergilenebilir, çünkü ekran görüntüsünden elde etmek istediğiniz bilgiler aslında başka bir yerde de saklanıyor olabilir ve farklı yöntemlerle de alınabilir.

Son söylediğim, etrafından dolandığıız yönteme dair bir makale , C# ile yazılmış ama size fikir vermesi açısından bunu python’a uyarlamak çok da zor değil. Ama asıl amaç anlaşılırsa daha farklı ve daha işe yarar çözümler bulabiliriz.

Capturing Minimized Window: A Kid’s Trick - CodeProject

3 Beğeni

Mükemmel bir anlatım teşekkür ederim.