Wincap ekran yakalama hatası: "BitBlt failed"

Merhaba arkadaşlar. Dosyayı çalıştırmaya çalıştığımda bu hatayı alıyorum.

Traceback (most recent call last):
  File "C:\Users\USER\Desktop\metin2bot\main.py", line 83, in <module>
    ss = wincap.get_screenshot()
  File "C:\Users\USER\Desktop\metin2bot\ekranyakala.py", line 58, in get_screenshot
    cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)
win32ui.error: BitBlt failed

Main.py dosyası

from cv2 import cv2
import numpy as np
import   os
from time import time, sleep
import pydirectinput, pyautogui, threading
from ekranyakala import ekranYakala
from vision import Vision

 
# from detection import Detection

os.chdir(os.path.dirname(os.path.abspath(__file__)))

# Pencere başlığı sürekli değiştiği için tüm başlıkları tek tek yazdım.
baslik = ("METIN2",
"Lucas2 - Global Farm Server - lucas2.online",
"Lucas2 - Facebook: facebook.com/Lucas2TR",
"Lucas2 - Wiki: rehber.lucas2.online",
"Lucas2 - Discord: discord.gg/lucas2",
"Lucas2 - Kaliteyi Hisset - lucas2.online")

# Pencerenin başlığı eşleşene kadar dönüyor.
for i in baslik:
    try:
        wincap = ekranYakala(i)
    except:
     continue

# Model dosyası
cascade = cv2.CascadeClassifier('C:/Users/USER/Desktop/metin2bot/cascade/cascade.xml')

vision = Vision(None)
loop_time = time()

metine_vur = False
s = 1
s1 = 0
kontrol = 0
def metinevur(rectangles):
    global metine_vur
    global kontrol
    global s, s1

    if len(rectangles) > 0:
        targets = vision.get_click_points(rectangles)
        target = wincap.get_screen_position(targets[0])
        pyautogui.moveTo(x=target[0], y=target[1])
        sleep( 0.1)
        pyautogui.rightClick(x=target[0], y=target[1]) #Bazı serverlarda sol click çalışmıyor. Burada da sağ click kullandık. Yine de sol click denemek isterseniz pyautogui.click bu kod ile değiştirin.
        print(s,"Metin Bulundu")
        sleep(1.2) #Metine gitme süresi. Metine tıkladıktan sonra kaç saniyede metine gittiği.1 yada 2 saniye yapın yeterli.
        pydirectinput.keyDown("space")
        sleep(2)  # Metin taşını kesme  hızınıza(saniye) göre bekletin. Yazdığınız saniye kadar space tuşuna basılı tutacak.
        pydirectinput.keyUp('space')
        s +=  1
        # Metin  taşını kesme  hızınıza(saniye) göre bekletin. Bu süreye dokunmayın. Space tuşu eklenince burası pasif durumda.
        sleep(0.1)
    else: 
        s1 += 1
        print(s1, "Bulunamadı")
        """
       e - Oyunda objeyi bulamazsa 6 defa 'e' tuşuna basar. yani ekranı döndürür.
        'f' ile kamerayı genişletir.
        - 3 defa bulamazsa 3 kez 'w'e basar ve ileri gider.

        Yani kısa cası burada yaptığımız işlem konum değiştirmek.
        Oynadığınız servere göre değiştirip geliştirebilirsiniz.

        Eğer oyun içinde tuş basmıyorsa programı yönetici olarak çalıştırıp deneyin.
        Yine olmazsa yapacak bişey yok :) yada ben bulamadım...
        """
        pydirectinput.press("e", presses=6)
        pydirectinput.press("f", presses=10)
        kontrol += 1
        #if kontrol >= 3:
            #print("Kontrol", kontrol)
            #pydirectinput.press("w", presses=3)
            #kontrol = 0

    metine_vur = False

while True:
    ss = wincap.get_screenshot()

    rectangles = cascade.detectMultiScale(ss)
    
    detection_image = vision.draw_rectangles(ss, rectangles)
    cv2.imshow('Goruntu', detection_image)

    if not metine_vur:
        """
       True, False kullanmamızın sebebi,
        Program sürekli döngüde kalacağı için,
        sadece 'false' durumlarda bu koşula girmesini istiyoruz.
        """

        metine_vur = True
        thrd = threading.Thread(target=metinevur, args=(rectangles))
        thrd.start()

        #FPS göster
        print("FPS {}".format(1 / (time() - loop_time)))
        loop_time = time()
    
        #Döngüden çık
        key = cv2.waitKey(1)
        if key == ord("q"):
         cv2.destroyAllWindows()
         print("Bot Durduruldu")
         break
    

Ekranyakala.py dosyası

import numpy as np
import win32gui, win32ui, win32con
from threading import Thread, Lock
import win32gui

class ekranYakala:
    stopped = True
    lock = None
    screenshot = None
    w = 0
    h = 0
    hwnd = None
    cropped_x = 0
    cropped_y = 0
    offset_x = 0
    offset_y = 0


    def __init__(self, window_name=None):
        # create a thread lock object
        self.lock = Lock()

        # find the handle for the window we want to capture.
        # if no window name is given, capture the entire screen
        if window_name is None:
            self.hwnd = win32gui.GetDesktopWindow()
        else:
            self.hwnd = win32gui.FindWindow(None, window_name)
            if not self.hwnd:
                raise Exception('Window not found: {}'.format(window_name))

        # get the window size
        window_rect = win32gui.GetWindowRect(self.hwnd)
        self.w = window_rect[2] - window_rect[0]
        self.h = window_rect[3] - window_rect[1]

        # account for the window border and titlebar and cut them off
        border_pixels = 8
        titlebar_pixels = 30
        self.w = self.w - (border_pixels * 2)
        self.h = self.h - titlebar_pixels - border_pixels
        self.cropped_x = border_pixels
        self.cropped_y = titlebar_pixels

        # set the cropped coordinates offset so we can translate screenshot
        # images into actual screen positions
        self.offset_x = window_rect[0] + self.cropped_x
        self.offset_y = window_rect[1] + self.cropped_y
    def get_screenshot(self):

        # get the window image data
        wDC = win32gui.GetWindowDC(self.hwnd)
        dcObj = win32ui.CreateDCFromHandle(wDC)
        cDC = dcObj.CreateCompatibleDC()
        dataBitMap = win32ui.CreateBitmap()
        dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
        cDC.SelectObject(dataBitMap)
        cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)

        # convert the raw data into a format opencv can read
        #dataBitMap.SaveBitmapFile(cDC, 'debug.bmp')
        signedIntsArray = dataBitMap.GetBitmapBits(True)
        img = np.fromstring(signedIntsArray, dtype='uint8')
        img.shape = (self.h, self.w, 4)

        # free resources
        dcObj.DeleteDC()
        cDC.DeleteDC()
        win32gui.ReleaseDC(self.hwnd, wDC)
        win32gui.DeleteObject(dataBitMap.GetHandle())

        # drop the alpha channel, or cv.matchTemplate() will throw an error like:
        #   error: (-215:Assertion failed) (depth == CV_8U || depth == CV_32F) && type == _templ.type() 
        #   && _img.dims() <= 2 in function 'cv::matchTemplate'
        img = img[...,:3]

        # make image C_CONTIGUOUS to avoid errors that look like:
        #   File ... in draw_rectangles
        #   TypeError: an integer is required (got type tuple)
        # see the discussion here:
        # https://github.com/opencv/opencv/issues/14866#issuecomment-580207109
        img = np.ascontiguousarray(img)

        return img

    @staticmethod
    def list_windowname():
        def winEnumHandler(hwnd, ctx):  #açık pencere isimlerini listeler
            if win32gui.IsWindowVisible(hwnd):
                print(hex(hwnd), win32gui.GetWindowText(hwnd))

        win32gui.EnumWindows(winEnumHandler, None)
    def get_screen_position(self, pos):
        return (pos[0] + self.offset_x, pos[1] + self.offset_y)

    def start(self):
        self.stopped = False
        t = Thread(target=self.run)
        t.start()
    def stop(self):
        self.stopped = True
    def run(self):
        while not self.stopped:
            screenshot = self.get_screenshot()
            self.lock.acquire()
            self.screenshot = screenshot
            self.lock.release()

ekranyakala.py de hata verdiği satır şurası:

        cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)

Main.py de hata verdiği 86. satır da şurası:

    ss = wincap.get_screenshot()

win32 kutuphanelerinin bir tanesinden GetLastError cagirabiliyor muyuz? BitBlt patladiktan hemen sonra cagirip return degerine bakmak lazim.

Bi de BitBlt'e giden parametrelerin degerleri neler?

Hocam yeniyim biraz basitçe anlatır mısınız hepsine cevap vereyim ?

Tamam, o zaman suradan baslayalim:

Cagirdigin fonksiyonun dokumentasyonunu okudun mu? Hangi durumlarda hata verebiliyormus?

Hayır bilmiyorum onu. Çağırdığım fonksiyon ekranyakala.py. Çalışan uygulamalardan

# from detection import Detection

os.chdir(os.path.dirname(os.path.abspath(__file__)))

# Pencere başlığı sürekli değiştiği için tüm başlıkları tek tek yazdım.
baslik = ("METIN2",
"Lucas2 - Global Farm Server - lucas2.online",
"Lucas2 - Facebook: facebook.com/Lucas2TR",
"Lucas2 - Wiki: rehber.lucas2.online",
"Lucas2 - Discord: discord.gg/lucas2",
"Lucas2 - Kaliteyi Hisset - lucas2.online")

# Pencerenin başlığı eşleşene kadar dönüyor.
for i in baslik:
    try:
        wincap = ekranYakala(i)
    except:
     continue

şuraya yazdığım başlıklı uygulamayı bulup yeni bir kopyasını açıyor. Hata vermiyordu daha önce bir sorun yoktu. 1 gündür böyle.

baslik = ()

bu kısıma oynadıgın serverin tam adını yaz

örnek:
baslik = (“Astra2”)

oyunu açtıktan sonra sol üst köşede ne yazıyorsa birebir aynısını yazmalısın boşluk olsun tırnak işareti olsun ne varsa yani

birebir aynısı yazıyor zaten hocam.

DC ver halledelim kanka

1 Beğeni

F0Rextasy(Halil)#5706

sa knk babacann#7097 bende aynı hatayı alıyorum yardım

hatayı düzelttiniz mi arkadaşlar
ss = wincap.get_screenshot()

aynı hata bendede mevcut