XNA Creators Club Online
Page 1 of 1 (7 items)
Sort Posts: Previous Next

Accesing pixels in the LPD3DXBUFFER

Last post 7/5/2009 5:13 AM by legalize. 6 replies.
  • 6/6/2009 12:52 PM

    Accesing pixels in the LPD3DXBUFFER

    Hi,

    i read the FrontBuffer and save it as a BMP file with D3DXSaveSurfaceToFileInMemory

    LPD3DXBUFFER pBuffer = NULL; 
    g_pd3dDevice->CreateOffscreenPlainSurface(1920, 1080, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &g_pSurface, NULL); 
    g_pd3dDevice->GetFrontBufferData(0, g_pSurface); 
    D3DXSaveSurfaceToFileInMemory(&pBuffer, D3DXIFF_BMP, g_pSurface, NULL,NULL);  

    now i wanna access the BMP file but i only know hot it works from the HDD

    // Variablen 
    HANDLE hfile; 
    DWORD written; 
    BITMAPFILEHEADER bfh; 
    BITMAPINFOHEADER bih; 
    RGBTRIPLE *image; 
    LONG imagesize; 
     
    //Einlesen 
    // Open the file 
    hfile = CreateFile(L"D:\Screenshot.bmp",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, NULL,NULL); 
    // Read the header 
    ReadFile(hfile,&bfh,sizeof(bfh),&written,NULL); 
    ReadFile(hfile,&bih,sizeof(bih),&written,NULL); 
    // Read image 
    imagesize = bih.biWidth*bih.biHeight; // Helps you allocate memory for the image 
    image = new RGBTRIPLE[imagesize]; // Create a new image (I'm creating an array during runtime) 
    ReadFile(hfile,image,imagesize*sizeof(RGBTRIPLE),&written,NULL); // Reads it off the disk 
    // Close source file 
    CloseHandle(hfile);  

    When i do it like this i have these handy RGPTRIPLE but i guess my pBuffer is no RGPTRIPLE  so how can i access the individual pixels?

    Thanks for you answers
  • 6/6/2009 2:08 PM In reply to

    Re: Accesing pixels in the LPD3DXBUFFER

    If you read the documentation on D3DXSaveSurfaceToFileInMemory you will see that this saves a BMP file in the memory buffer so you can just use the pointer it goves you back as a file handle to a file in memory. What this means is that instead of having the file on the HDD its in RAM. The actual memory stream is just a full BMP image with header and everything
  • 6/6/2009 2:20 PM In reply to

    Re: Accesing pixels in the LPD3DXBUFFER

    so i just use

    ReadFile(pBuffer,&bfh,sizeof(bfh),&written,NULL);

    and skip the whole

    CreateFile

    thanks
  • 6/6/2009 4:23 PM In reply to

    Re: Accesing pixels in the LPD3DXBUFFER

    When i use

    ReadFile(pBuffer,image,imagesize*sizeof(RGBTRIPLE),&written,NULL); 

    the compiler does not complain but when i run my code i get an error

    Unhandled exception at 0x765b98f6 in Ambilight.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0039f46c..

    because

    ReadFile(pBuffer,&bfh,sizeof(bfh),&written,NULL); 
    ReadFile(pBuffer,&bih,sizeof(bih),&written,NULL); 


    does not read the correct values. for example bih.width = -858993460

    i guess i cannot just replace the handle with the pbuffer

    could i get a bit more help? =D

    EDIT: got it

        memcpy(&bfh,pBuffer,sizeof(bfh)); 
        memcpy(&bih,pBuffer,sizeof(bih)); 
        imagesize = pBuffer->GetBufferSize();// Helps you allocate memory for the image 
        image = new RGBTRIPLE[imagesize]; // Create a new image (I'm creating an array during runtime) 
         
         
        memcpy(image,pBuffer,imagesize*sizeof(RGBTRIPLE)); 

    but now i get an error

    Unhandled exception at 0x69fafe06 (msvcr90d.dll) in Ambilight.exe: 0xC0000005: Access violation reading location 0x0020c000.

    i guess it is because imagesize*sizeof rgb is too large but i dont know why.

    if i choose a size myself in memcpy like 1*sizeof(RGBTRIPLE) or 100*sizeof(RGBTRIPLE) i dont get an error but only image[0] recieves new values... all others image[1] etc remain empty. so i guess i cannot use memcpy??? but why does it work with bih and bfh?

    the falues of bfh and bih are kind of okay but bih.width is 1 and bih.height is 8MB
    and the first falue of image is okay too.
    another problem is how do i acces the pixel in my image array... because i cant  use

    image[(bih.biHeight-1-y)*bih.biWidth+x]; 

    since i cant get the bih out of my pbuffer correctly
  • 6/6/2009 10:46 PM In reply to

    Re: Accesing pixels in the LPD3DXBUFFER

    No because a handle is not a pointer to the actual data, its a smart pointer type. The D3DXBuffer object actually contains the data.
    What you can alternativly do is save the image to a texture and then lock the buffer and get hold of the pointer to the actual data in there. That data will contain the RGBA values for the texture, read up on the Pitch value there, you can interogate the width and height on a texture keep in mind that this is slow due to the fact that you need to read data back from the GPU. The other thing you could do is create a texture in sysmemory from the D3DXBuffer you have now and lock that texture and read the pixel data out.
  • 6/8/2009 12:45 PM In reply to

    Re: Accesing pixels in the LPD3DXBUFFER

    But with pBuffer->GetBufferSize i get a pointer to the actual data and reading out the bfh works. And why would they have a function savefiletomemory when you cant access the file afterwards...
  • 7/5/2009 5:13 AM In reply to

    Re: Accesing pixels in the LPD3DXBUFFER

    Its not a file because files are in the filesystem and this isn't in the filesystem, its just a pile of bytes in memory. If you write the bytes out to a file in the filesystem and open it as a file, then you can call ReadFile and other file APIs on the data.

    The data is saved in memory using whatever file format (PNG, BMP, etc.) you told D3DX to use, but it isn't written out to a file in the filesystem. If you want to write to a file in the filesystem, use D3DXSaveSurfaceToFile.

    More details on these functions can be found in Chapter 15. D3DX Utility Library of my book The Direct3D Graphics Pipeline.

Page 1 of 1 (7 items) Previous Next