Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Capture image data from portion of the screen?  (Read 16147 times)

0 Members and 1 Guest are viewing this topic.

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Capture image data from portion of the screen?
« on: February 05, 2014, 04:00:45 am »
Hi all, is it possible with SFML to capture a portion of the users screen (what's being displayed on their monitor as well as hidden views (when have multiple monitors)) and quickly display it in real-time inside the SFML app?

If so how should it be done? Should I use sprites or textures?

If SFML doesn't have such a feature, does anyone know how I can achieve this and then use SFML to display it?

Thanks in advance  8)
« Last Edit: February 05, 2014, 08:20:36 am by Pheonix »
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #1 on: February 05, 2014, 04:11:42 am »
Are you creating an invisibility cloak? lol!

I'm not sure its trivial to do, but you will probably be using the OS API to fetch that bitmap data.. The problem is that buffer you get from the OS will usually include your own window too.. Not sure how to solve the problem..

Assuming you could do that and get the screen bitmap data you could easily render it to the entire window and achieve your invisibility cloak :P (don't forget to make the window borderless and without title bar)

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #2 on: February 05, 2014, 04:22:27 am »
Quote
OS will usually include your own window too.. Not sure how to solve the problem..

No no... it's okay if it captures the apps window too. I just wanted to emphasize the fact that I wanted to capture the screen, as in, 'the users whole screen', not the 'apps screen'.  :P
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Capture image data from portion of the screen?
« Reply #3 on: February 05, 2014, 04:35:39 am »
You almost definitely need the API of OS and to watch out which frame you capture (one with your window in it or not etc.) but you can hide own window with setVisible(false); if you need to.
Back to C++ gamedev with SFML in May 2023

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #4 on: February 05, 2014, 06:34:44 am »
 :'(

Is there anyone experience in this that can make a working code? I have looked at almost a dozen codes through google and haven't found anything that works, let alone integrate it into SFML.
« Last Edit: February 05, 2014, 11:32:11 am by Pheonix »
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #5 on: February 05, 2014, 12:51:34 pm »
http://stackoverflow.com/questions/3291167/how-to-make-screen-screenshot-with-win32-in-c

After googling for 30 seconds I found that, it seems to do what you want (hopefully). You just do that and then use the HBITMAP structure to extract the pixel data, check the windows API documentation on how to do that.

From there, you can easily convert to a sf::Image and after that to a regular sf::Texture to use with a sprite. Be careful with pixel formats tho, might get tricky if you are not paying attention :)

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #6 on: February 05, 2014, 01:25:28 pm »
Yeah, I already saw that one. I cannot get the code to build however.
« Last Edit: February 06, 2014, 12:56:35 am by Pheonix »
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #7 on: February 05, 2014, 02:30:54 pm »
Then don't stop at these errors and google (or whatever is your favorite search engine) them, take a look at the documentations of the function you use, etc. ???

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #8 on: February 05, 2014, 04:38:03 pm »
Ill give you a tip on how to solve the first error, you search the rest.

Many windows API functions come in two variants, when they deal with strings, to receive ansi and wide strings. They are identified by a A or W suffix, respectively.

In your case, you are calling CreateDC, which is redirected automatically to CreateDCW, as it is assuming wide string by default. Try explicitly calling CreateDCA OR actually send a wide string to CreateDC by prepending an L before the string (L"MyWideString")

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #9 on: February 06, 2014, 06:26:40 am »
Here is an update of the code with some help from other people in other forums who know a bit more about windows functions.

#include <Windows.h>
#include <SFML/Graphics.hpp>

int main()
{
        // (1) get the device context of the screen
        // Definition: The CreateDC function creates a device context (DC)
        //      ..for a device using the specified name.
        HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);  

        // (2) and a device context to put it in
        // Definition: The CreateCompatibleDC function creates a memory
        //      ..device context (DC) compatible with the specified device.
        HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

        // (3) Gets the users screen size in x and y dimensions
        // Definition: The GetDeviceCaps function retrieves device-specific
        //      ..information for the specified device.
        int x = GetDeviceCaps(hScreenDC, HORZRES);
        int y = GetDeviceCaps(hScreenDC, VERTRES);

        // (4) maybe worth checking these are positive values
        // Definition: The CreateCompatibleBitmap function creates a bitmap
        //      ..compatible with the device that is associated with the specified
        //      ..device context.
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);

        // (5) get a new bitmap
        // Definition: The SelectObject function selects an object into the
        //      ..specified device context (DC). The new object replaces the previous
        //      ..object of the same type.
        HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

        // Definition: The BitBlt function performs a bit-block transfer of the
        //      ..color data corresponding to a rectangle of pixels from the specified
        //      ..source device context into a destination device context.
        BitBlt(hMemoryDC, 0, 0, x, y, hScreenDC, 0, 0, SRCCOPY);


        // Don't need this apparently
        //hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);

        //////////////////////////////////////////////////////////////////////////////////

        // Create the SFML Window
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");

        // Load the bitmap from memory into texture
        sf::Texture Texture;
        Texture.loadFromMemory(hOldBitmap,sizeof(hOldBitmap));

        // Load the texture into a sprite
        sf::Sprite Sprite;
        Sprite.setTexture(Texture);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
                window.draw(Sprite);
        window.display();
    }

        // clean up
        DeleteDC(hMemoryDC);
        DeleteDC(hScreenDC);

    return 0;
}
 

Still crashes however when run... Though I think it is an SFML issue. However, I'm not confident that the Windows part is completely right either..
« Last Edit: February 06, 2014, 06:49:54 am by Pheonix »
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #10 on: February 06, 2014, 06:32:26 am »
Here is an update of the code with some help from other people in other forums who know a bit more about windows functions.

...

Still crashes however when run... Though I think it is an SFML issue.

"Hey, I went to a forum where people know more than you guys. They are so awesome that they fixed my 2 missing symbols, which solution was already given by you guys previously. But besides all the smartness, it doesn't run at all, because I am just doing something random when uploading my bitmap data, something which ALSO been warned about before in this forum of people that don't know enough about windows functions."

Good luck, I give up

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #11 on: February 06, 2014, 06:39:15 am »
You misinterpreted/exaggerated what I was trying to say. Don't take it personally.   ::)

What I meant to say was that I asked some people who understand what I'm trying to do for the Windows part and then update my thread here... (so if the code changed you didn't think I was just randomly changing stuff - for the windows part, anyway)

This is an SFML forum after all, I can't expect anyone here to know Windows stuff, let alone specifically what I'm trying to do. It's hard to find people who know both SFML and Windows to a high degree, and I cannot figure out the Windows stuff out on my own since it's completely new to me.
« Last Edit: February 06, 2014, 06:51:00 am by Pheonix »
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #12 on: February 06, 2014, 06:52:04 am »
You don't need to know anything to a high degree when you have good documentation. That's the whole point of writing documentation, so everyone has access to the API. Speaking of API, if you took some time to google how to extract pixel data from a HBITMAP and then put it in a sf::Image like we told you, your problem would be solved already.

http://msdn.microsoft.com/en-us/library/windows/desktop/dd144850(v=vs.85).aspx

Speaking of high degree knowledge, that's not what this is.. This is a trivial task you were able to just copy paste from stack overflow.. You didn't need to be einstein to prepend an L in your strings without getting to winAPI tech support forums :p

Pheonix

  • Newbie
  • *
  • Posts: 27
  • Using SFML 2.1 with Win/Visual C++ (Newbie !!!)
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #13 on: February 06, 2014, 06:56:10 am »
I'm sure you are like some people, very good at reading APIs and Wikipedia articles, even if its about things you know nothing about. Not everyone is like you. Most of the time when I read APIs I get completely lost and have no idea what they're on about.

If I had a bit more knowledge in these things maybe it would be easier...

Anyway, it's hardly my fault it's so damn difficult! That you need to type so much code, read so much documentation to do something this simple... And then when you finally have a 'bitmap' stored in memory you still can't use it, because it's a different type of 'bitmap'...  >:(
« Last Edit: February 06, 2014, 07:00:01 am by Pheonix »
Using SFML 2.1 with Win/Visual C++ (Newbie !!!)

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Capture image data from portion of the screen?
« Reply #14 on: February 06, 2014, 07:05:17 am »
Okay mate. I am sorry I was rude to you. I still think your behavior wasn't the most appropriate but I want to apologize for mine.

Give me some seconds and ill find this out for you and paste the code here.