2010-04-17 16 views
11

मैं एक आयताकार क्षेत्र, या पूरे स्क्रीन पिक्सल पढ़ना चाहता हूं। जैसे कि स्क्रीनशॉट बटन दबाया गया था।स्क्रीन पिक्सल को कैसे पढ़ा जाए?

मैं यह कैसे करता हूं?

संपादित करें: कार्य कोड:

void CaptureScreen(char *filename) 
{ 
    int nScreenWidth = GetSystemMetrics(SM_CXSCREEN); 
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN); 
    HWND hDesktopWnd = GetDesktopWindow(); 
    HDC hDesktopDC = GetDC(hDesktopWnd); 
    HDC hCaptureDC = CreateCompatibleDC(hDesktopDC); 
    HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight); 
    SelectObject(hCaptureDC, hCaptureBitmap); 

    BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0,0, SRCCOPY|CAPTUREBLT); 

    BITMAPINFO bmi = {0}; 
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); 
    bmi.bmiHeader.biWidth = nScreenWidth; 
    bmi.bmiHeader.biHeight = nScreenHeight; 
    bmi.bmiHeader.biPlanes = 1; 
    bmi.bmiHeader.biBitCount = 32; 
    bmi.bmiHeader.biCompression = BI_RGB; 

    RGBQUAD *pPixels = new RGBQUAD[nScreenWidth * nScreenHeight]; 

    GetDIBits(
     hCaptureDC, 
     hCaptureBitmap, 
     0, 
     nScreenHeight, 
     pPixels, 
     &bmi, 
     DIB_RGB_COLORS 
    ); 

    // write: 
    int p; 
    int x, y; 
    FILE *fp = fopen(filename, "wb"); 
    for(y = 0; y < nScreenHeight; y++){ 
     for(x = 0; x < nScreenWidth; x++){ 
      p = (nScreenHeight-y-1)*nScreenWidth+x; // upside down 
      unsigned char r = pPixels[p].rgbRed; 
      unsigned char g = pPixels[p].rgbGreen; 
      unsigned char b = pPixels[p].rgbBlue; 
      fwrite(fp, &r, 1); 
      fwrite(fp, &g, 1); 
      fwrite(fp, &b, 1); 
     } 
    } 
    fclose(fp); 

    delete [] pPixels; 

    ReleaseDC(hDesktopWnd, hDesktopDC); 
    DeleteDC(hCaptureDC); 
    DeleteObject(hCaptureBitmap); 
} 
+1

जवाब स्वीकार करने के लिए अगर वे आपकी मदद कर मत भूलना। – Johnsyweb

+0

मुझे पता है, मुझे यह काम अभी तक मिल गया है – Newbie

+0

शायद आपको कुछ और जानकारी जोड़ने की ज़रूरत है जैसे आपने कोशिश की है और क्या असफल रहा है। – Johnsyweb

उत्तर

7

अपने कोड के साथ शुरू और त्रुटि जाँच को छोड़ते हुए ...

// Create a BITMAPINFO specifying the format you want the pixels in. 
// To keep this simple, we'll use 32-bits per pixel (the high byte isn't 
// used). 
BITMAPINFO bmi = {0}; 
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); 
bmi.bmiHeader.biWidth = nScreenWidth; 
bmi.bmiHeader.biHeight = nScreenHeight; 
bmi.bmiHeader.biPlanes = 1; 
bmi.bmiHeader.biBitCount = 32; 
bmi.bmiHeader.biCompression = BI_RGB; 

// Allocate a buffer to receive the pixel data. 
RGBQUAD *pPixels = new RGBQUAD[nScreenWidth * nScreenHeight]; 

// Call GetDIBits to copy the bits from the device dependent bitmap 
// into the buffer allocated above, using the pixel format you 
// chose in the BITMAPINFO. 
::GetDIBits(hCaptureDC, 
      hCaptureBitmap, 
      0, // starting scanline 
      nScreenHeight, // scanlines to copy 
      pPixels, // buffer for your copy of the pixels 
      &bmi, // format you want the data in 
      DIB_RGB_COLORS); // actual pixels, not palette references 

// You can now access the raw pixel data in pPixels. Note that they are 
// stored from the bottom scanline to the top, so pPixels[0] is the lower 
// left pixel, pPixels[1] is the next pixel to the right, 
// pPixels[nScreenWidth] is the first pixel on the second row from the 
// bottom, etc. 

// Don't forget to free the pixel buffer. 
delete [] pPixels; 
+0

क्या मैंने hCaptureBitmap के लिए रखा है? – Newbie

+0

इसके अलावा, मैं कौन सी खिड़की एचडीसी रखता हूं, मेरा डेस्कटॉप या मेरा प्रोग्राम अपनी खिड़की? – Newbie

+0

मेरे संपादन को देखो, मैंने अपना कोड अपडेट किया है, इसमें क्या गलत है? – Newbie

6

प्रारंभ यहाँ Various methods for capturing the screen

+0

मैं पहले उदाहरण फ़ंक्शन में कॉपी की गई स्मृति को कैसे एक्सेस करूं? मैंने hCaptureBitmap [0] के मान को आउटपुट करने का प्रयास किया लेकिन यह दुर्घटनाग्रस्त हो गया। – Newbie

+1

@Newbie: डिवाइस-निर्भर बिटमैप से डिवाइस-स्वतंत्र बिटमैप में पिक्सल प्राप्त करने के लिए 'GetDIBits' का उपयोग करें। फिर आप उस से पिक्सल तक पहुंच सकते हैं। वैकल्पिक रूप से, आप एक डीआईबी अनुभाग बिटमैप बना सकते हैं और प्रारंभिक कैप्चर के लिए इसका उपयोग कर सकते हैं। –

+0

फ़ंक्शन परिभाषा मेरे लिए कुल गड़बड़ी है। कई कीवर्ड हैं जो मुझे नहीं पता कि उनका क्या मतलब है ... मुझे इसे पूरी तरह से समझने के लिए प्रत्येक कीवर्ड से दूसरे कीवर्ड में रिकर्सली करना होगा, इसमें सप्ताह लगेंगे। तो ... मैं अब अन्य समस्याओं के साथ थोड़ी व्यस्त हूं, मेरे पास अब इसके लिए समय नहीं है। यदि आप चाहते हैं, तो आप इस प्रश्न का उत्तर दे सकते हैं और कोड का एक कार्य टुकड़ा पेश कर सकते हैं, फिर मैं इसे सही उत्तर के रूप में स्वीकार कर सकता हूं और आभारी रहूंगा। – Newbie

2

आप BitBlt साथ एक स्क्रीनशॉट() बनाते हैं। शॉट का आकार nWidth और nHeight तर्कों के साथ सेट किया गया है। ऊपरी बाएं कोने nXSrc और nYSrc तर्कों के साथ सेट है।

0

एचबीआईटीएमएपी एक सूचक या सरणी नहीं है, यह एक हैंडल है जो विंडोज द्वारा प्रबंधित किया जाता है और इसका मतलब केवल विंडोज़ है। आपको विंडोज़ को पिक्सेल को कहीं भी उपयोग के लिए कॉपी करने के लिए कहा जाना चाहिए।

व्यक्तिगत पिक्सेल मान प्राप्त करने के लिए, आप बिटमैप की आवश्यकता के बिना GetPixel का उपयोग कर सकते हैं। यदि आपको कई पिक्सल तक पहुंचने की आवश्यकता है तो यह धीमा हो जाएगा।

मेमोरी में बिटमैप की प्रतिलिपि बनाने के लिए आप GetDIBits function का उपयोग कर सकते हैं।

2

अपने प्रश्न को दोबारा पढ़ना, ऐसा लगता है जैसे हम स्क्रीन कैप्चर के साथ टेंगेंट पर उतर गए होंगे। यदि आप स्क्रीन पर कुछ पिक्सल देखना चाहते हैं, तो आप GetPixel का उपयोग कर सकते हैं।

HDC hdcScreen = ::GetDC(NULL); 
COLORREF pixel = ::GetPixel(hdcScreen, x, y); 
ReleaseDC(NULL, hdcScreen); 
if (pixel != CLR_INVALID) { 
    int red = GetRValue(pixel); 
    int green = GetGValue(pixel); 
    int blue = GetBValue(pixel); 
    ... 
} else { 
    // Error, x and y were outside the clipping region. 
} 

आप पिक्सल का एक बहुत पढ़ने के लिए जा रहे हैं, तो आप एक स्क्रीन पर कब्जा और फिर GetDIBits उपयोग करने के साथ बेहतर कर रहे हैं। कॉलिंग GetPixel ज़िलियन बार धीमा हो जाएगा।

+0

हाँ, मैं पिक्सेल के आयत को पढ़ना चाहता हूं (या पूरी स्क्रीन एक बार अगर यह आसान हो)। मुझे नहीं पता कि GetDIBits फ़ंक्शन का उपयोग कैसे करें, मैं पैरामीटर के लिए किसी भी शब्द को समझ नहीं पाया, मुझे नहीं पता कि यह कैसे काम करता है। – Newbie

+0

मुझे आपके काम को काम करने के लिए मिला है, लेकिन मैं 1 पिक्सेल से अधिक पढ़ने के लिए और अधिक कुशल तरीका का उपयोग करना चाहता हूं। मैं इस GetDIBits फ़ंक्शन को काम नहीं कर सकता। – Newbie

संबंधित मुद्दे