Screenshot



  • Hallo,

    ich hab mir nen Screenshotprogramm gebastelt ,jedoch kann ich keine
    Bilder von meinem Software DVD Player bekommen. Dieser bereich ist immer schwarz. Woran liegt dass?

    Ich benutze:

    int Ctest::dc2bitmap(HDC hdc, int width, int height, char *filename) 
    { 
        HDC hdc2; 
        HBITMAP aBmp; 
        BITMAPINFO bi; 
        HGDIOBJ OldObj; 
        void *dibvalues; 
        HANDLE fileHandle; 
    
        BITMAPFILEHEADER bmfh; 
        BITMAPINFOHEADER bmih; 
            DWORD bytes_write; 
        DWORD bytes_written; 
    
        hdc2=CreateCompatibleDC(hdc); 
    
        ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER)); 
        bmih.biSize=sizeof(BITMAPINFOHEADER); 
          bmih.biHeight=height; 
            bmih.biWidth=width; 
            bmih.biPlanes=1; 
            bmih.biBitCount=24; 
        bmih.biCompression=BI_RGB; 
        bmih.biSizeImage = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) >> 3) * bmih.biHeight; 
            bmih.biXPelsPerMeter = 0; 
            bmih.biYPelsPerMeter = 0; 
            bmih.biClrImportant = 0; 
        //bmih.biSizeImage=(3*bmih.biHeight*bmih.biWidth); 
            //bmih.biSizeImage = 0; 
    
        bi.bmiHeader=bmih; 
    
        aBmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL); 
    
        if (aBmp==NULL) 
        { 
            OutputDebugString("CreateDIBSection failed!\n"); 
            return 0; 
        } 
    
        OldObj=SelectObject(hdc2,aBmp); 
        BitBlt(hdc2,0,0,width,height,hdc,0,0,SRCCOPY); 
    
        ZeroMemory(&bmfh,sizeof(BITMAPFILEHEADER)); 
        bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); 
        bmfh.bfSize=(3*bmih.biHeight*bmih.biWidth)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); 
            bmfh.bfType=0x4d42; 
            bmfh.bfReserved1 = 0; 
            bmfh.bfReserved2 = 0; 
    
        fileHandle=CreateFile(filename,GENERIC_READ | GENERIC_WRITE,(DWORD)0,NULL, 
                                                        CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE) NULL); 
        if (fileHandle==INVALID_HANDLE_VALUE) 
        { 
            OutputDebugString("CreateFile failed!\n"); 
            return 0; 
        } 
    
            // Write the BITMAPFILEHEADER 
            bytes_write=sizeof(BITMAPFILEHEADER); 
        if (!WriteFile(fileHandle,(void*)&bmfh,bytes_write,&bytes_written,NULL)) 
        { 
            OutputDebugString("WriteFile failed!\n"); 
            return 0; 
        } 
    
            //Write the BITMAPINFOHEADER 
        bytes_write=sizeof(BITMAPINFOHEADER); 
        if (!WriteFile(fileHandle,(void*)&bmih,bytes_write,&bytes_written,NULL)) 
        { 
            OutputDebugString("WriteFile failed!\n"); 
            return 0; 
        } 
    
            //Write the Color Index Array??? 
            bytes_write=bmih.biSizeImage;//3*bmih.biHeight*bmih.biWidth; 
        if (!WriteFile(fileHandle,(void*)dibvalues,bytes_write,&bytes_written,NULL)) 
        { 
            OutputDebugString("WriteFile failed!\n"); 
            return 0; 
        } 
    
        CloseHandle(fileHandle); 
    
        DeleteObject(SelectObject(hdc2,OldObj)); 
        DeleteDC(hdc2); 
    
        return 1; 
    }
    

    und

    hdc=GetWindowDC(GetDesktopWindow());
    


  • Liegt imho daran, dass diese ihre Daten dirakt an die Grafik-Hardware senden 🙄
    Wie man trotzdem drankommt weiß ich leider nicht 😞



  • Hmm....

    kannst Du evtl. vorher das "Videoanzeigefenster" als TOPMOST setzen und den Fokus auf dieses Fenster setzen?



  • Selbst wenn der DVd Player das aktuelle fenster ist und ich

    GetWindowRect(GetForegroundWindow(), &rect);
    

    benutze seh ich nur eine schwarze Fläche, wo der Film sein sollte.

    Komisch ist es wenn ich den Windows Media Player benutze, dann klappt es mal und mal nicht ca 50 : 50 ist da die Chance.
    (Screibt dieser mal direkt in den Grafikkartenram und mal nicht?)

    Wie kann ich das Problem beheben?



  • Vielleicht die Grafikkarte irgendwie ausschalten?



  • DVD-Videos werden grundsätzlich über Overlay angezeigt. Das läuft wie schon gesagt direkt über die Grafikkarte, sodass Windows (und seine HDCs) davon überhauptnichts mitbekommen.

    Schaff dir eine Uralt-Grafikkarte an, die kein Overlay beherrscht (z.B. eine PCI-Karte). Dann geht es.
    Ich hatte mal eine kurze Zeit eine PCI-Karte in meinem Rechner. DVDs konnte ich erstaunlicherweise nur noch mit PowerDVD gucken. Der Zoomplayer hat nur eine schwarze Fläche angezeigt, obwohl er eigentlich dieselben Decoder-DLLs benutzt (die von PowerDVD).
    Aber der Screenshot war einwandfrei. 🙂

    Tipp: Wenn es dir nur um einzelne Screenshots geht:
    Bei PowerDVD kann man einzelne Frames des Videos als Bitmap speichern (das klappt IMHO auch bei DVDs). Dann kannst du dir den Screenshot in kurzer Zeit zusammenflicken.



  • Mir geht es nicht um die Bilder sondern um das Basteln des Screenshot Programms
    und es gibt einige Programme die Bilder von DVD Playern erstellen können.

    Es geht ja auch mit Getpixel(), da ist aber das Problem dass es zu lange dauert
    und man deshalb eine Kombination aus mehreren Bildern bekommt.



  • Vielleicht irgendwie mit GetDIBits - bin mir aber nicht so sicher 🙄



  • GetDIBits:
    Die GetDIBits Funktion ermittelt die Bits der angegebenen Bitmap und kopiert sie in einem geräteunabhängigem Format in den bezeichneten Puffer.

    Beispiel:

    int  test (HDC screendc,char *filename ) {
    
      HDC memdc;
      HBITMAP hbitmap;
      BITMAP  bmp;
      memdc    = CreateCompatibleDC(screendc);
      hbitmap  = CreateCompatibleBitmap(screendc, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));  SelectObject(memdc, hbitmap);
      BitBlt(memdc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), screendc, 0, 0, SRCCOPY);  if(GetObject(hbitmap, sizeof(BITMAP), &bmp))
       {
         BITMAPINFOHEADER BmpInfoHdr;
         BITMAPFILEHEADER BmpFileHdr;     BmpInfoHdr.biSize        = sizeof(BITMAPINFOHEADER);
         BmpInfoHdr.biWidth       = bmp.bmWidth;
         BmpInfoHdr.biHeight      = bmp.bmHeight;
         BmpInfoHdr.biPlanes      = bmp.bmPlanes;
         BmpInfoHdr.biBitCount    = 24;
         BmpInfoHdr.biCompression = BI_RGB;
         BmpInfoHdr.biSizeImage   = bmp.bmWidth*bmp.bmHeight*3;     
    	 BmpFileHdr.bfType      = 0x4d42;
         BmpFileHdr.bfReserved1 = 0;
         BmpFileHdr.bfReserved2 = 0;
         BmpFileHdr.bfOffBits   = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
         BmpFileHdr.bfSize      = BmpFileHdr.bfOffBits+BmpInfoHdr.biSizeImage;     bmp.bmBits = (void*)GlobalAlloc(GMEM_FIXED, BmpInfoHdr.biSizeImage);     
    	 if(GetDIBits(screendc, hbitmap, 0, BmpInfoHdr.biHeight, bmp.bmBits, (BITMAPINFO*)&BmpInfoHdr, DIB_RGB_COLORS) == BmpInfoHdr.biHeight)
          {
            HANDLE hFile = CreateFile(filename,
                                      GENERIC_READ | GENERIC_WRITE,
                                      0,
                                      NULL,
                                      CREATE_ALWAYS,
                                      FILE_ATTRIBUTE_NORMAL,
                                      NULL);        if(hFile != INVALID_HANDLE_VALUE)
             {
               DWORD dwTmp;           WriteFile(hFile, &BmpFileHdr, sizeof(BITMAPFILEHEADER), &dwTmp, NULL);
               WriteFile(hFile, &BmpInfoHdr, sizeof(BITMAPINFOHEADER), &dwTmp, NULL);
               WriteFile(hFile, bmp.bmBits,  BmpInfoHdr.biSizeImage,   &dwTmp, NULL);
             }
            CloseHandle(hFile);
          }
         GlobalFree(bmp.bmBits);
       }  RestoreDC(memdc, -1);
      ReleaseDC(0, screendc);
      DeleteObject(hbitmap); 
      return 0;
    
    }
    

    Ich meine diese Funktion nützt mir nichts, da ich ja noch kein bmp habe!

    Hat noch Jemand ne Idee?



  • Probiers mit DirectX ...



  • Ich kenne dieses lästige Problem auch.

    Wenn Du ein anderes Video (szsg. ein dummy) "hidden" aufrufst – bevor das eigentliche Video aufgerufen wird! – ist der Overlay-Modus der Grafikkarte damit beschäftigt. Jetzt kannst Du problemlos, wie gehabt, Deine screenshots machen.

    Liebe Grüsse

    Johannes

    P.S. Tests doch mal:

    Lass irgendein Video z.B. mit dem Mediaplayer laufen und rufe nun ein zweites Video mit einem weiteren Player auf. Wenn Du jetzt nen screenshot machst ist das zweite Bild zu sehen.



  • @AndreasXXL: hi... hast du eine lösung für dein problem gefunden?

    ich arbeite mom. an einem ähnlichen problem und würde mich über konstruktive hilfe sehr freuen 🙂

    siehe hier



  • Hallo,

    gut, dass sich noch Jemand zur Zeit mit diesem Problem beschäftigt.
    Ich hatte eigentlich bezüglich der Videos aufgegeben und versuche nun wenigstens die Bilder auch als *.jpg abzuscpeichern. Aber selbst das hab ich noch nicht geschafft. Wenn du irgendeinen neuen Ansatz für die Videos gefunden hast ( ausser 2 gleichzeitig laufen zu lassen) bin ich aber noch sehr interessiert daran.

    Ps. Wenn du das Abspeichern als *.jpg hinbekommst bitte posten! Danke


Anmelden zum Antworten