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

Author Topic: sf::Image::loadFromMemory read access violation  (Read 1258 times)

0 Members and 1 Guest are viewing this topic.

alimao

  • Newbie
  • *
  • Posts: 5
    • View Profile
sf::Image::loadFromMemory read access violation
« on: July 18, 2022, 07:41:25 pm »
so what im trying to do is take a screenshot from the entire screen(not only from sfml window) and saving it to memory to then save to a file (i am trying to just save to memory but to debug i am saving) and it gives me the error at the title (i am only using 1 file for a while)

#include "functions.h"
#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <Windows.h>

#undef IS_USING_TEXT

void* screenCapturePart() {
        HDC hdcSource = GetDC(NULL);
        HDC hdcMemory = CreateCompatibleDC(hdcSource);

        int capX = GetDeviceCaps(hdcSource, HORZRES);
        int capY = GetDeviceCaps(hdcSource, VERTRES);

        HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, 1920, 1080);
        HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);

        BitBlt(hdcMemory, 0, 0, 1920, 1080, hdcSource, 0, 0, SRCCOPY);
        hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);

        return hBitmap;
}

int WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
#ifdef IS_USING_TEXT
        static auto defFont = new sf::Font;
        defFont->loadFromFile("Roboto-Regular.ttf");
#endif // IS_USING_TEXT

        sf::RenderWindow window(sf::VideoMode(800u, 800u), "SFML", sf::Style::Close);
        window.setVerticalSyncEnabled(true);
        sf::Event evnt;

        sf::Image screenshot;
        screenshot.loadFromMemory(screenCapturePart(), (size_t)1920 * 1080 * sizeof(sf::Color));

        if (screenshot.saveToFile("z.bmp"))
                window.close();

        while (window.isOpen())
        {
               

                ProcessEvents(window, evnt);
                window.clear();
               
                window.display();
        }
       
#ifdef IS_USING_TEXT
        delete defFont;
#endif // IS_USING_TEXT
        return 0;
}

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: sf::Image::loadFromMemory read access violation
« Reply #1 on: July 19, 2022, 03:38:32 am »
As far as I'm aware:
CreateCompatibleBitmap() makes a device dependent bitmap. This means hBitmap contains a handle to a bitmap that may (most likely is) stored in graphics memory which you can't directly access. To read the raw data of it you need a device independent bitmap (which is made in main memory).
You can get the pixel data from a HBITMAP using GetDIBits(), which copies the memory into a block you allocated.

Have a look at the answer here, it shows getting a pointer to a HBITMAP's data and accessing it: https://stackoverflow.com/questions/35762636/raw-direct-acess-on-pixels-data-in-a-bitmapinfo-hbitmap

So you'd:
- create BITMAPINFOHEADER
- allocate a big enough block of memory
- GetDIBits to copy hBitmap into memory
- use the block of memory with SFML's loadFromMemory.

Also you aren't cleaning up the DC or HBITMAP, so it will leak memory if you call screenCapturePart several times.

Although I've never done this myself, I just googled around. I've never liked GDI stuff. :)

alimao

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: sf::Image::loadFromMemory read access violation
« Reply #2 on: July 19, 2022, 01:48:01 pm »
thaks fot the reply but i think my projects not going to work because of other things that i realise it will not work

 

anything