Game Development Community

generate or export png from screen

by Brian Carlson · in Torque 2D Beginner · 12/23/2015 (1:03 pm) · 6 replies

Hello,
I am in the early stages of learning Torque 2D, and I was wondering if there is a way to save an image from the assets on-screen. This would be very similar to just pressing the Print Screen button on your keyboard, but I'd like my game/program to be smart about it, like cropping the image and ignoring any menus that happen to be on-screen at the time.
Thank you,
Brian

#1
12/23/2015 (2:00 pm)
Not built-in. But it does use pnglib, so the tools are there.
#2
12/24/2015 (9:14 am)
Thanks!
#3
12/30/2015 (8:19 am)
We did something like this internally while working on 3 Step Studio, I believe for the Blackjack template. Did you figure this out yet Brian? If not, I can provide some info.
#4
12/30/2015 (1:29 pm)
Wait - it was in 3SS? Aw man....
#5
12/30/2015 (2:52 pm)
Michael,
I decided to work through my problem in a different way. I am learning to program with Torque 2D (as a hobby for the time being), but I'm pursuing the print screen issue with another program (for my day job).
It's not a pressing concern for me right now, but I'm sure it would be great to know for the future, or if others here want to know, some direction on this would be much appreciated.
#6
12/31/2015 (8:22 am)
@Brian - Ok. I'll add some more info. As Richard said, libpng is a great solution if you are using C++. Here is a portion of the code in our PNGImage class, which is most relevant:

ConsoleFunction(CaptureScreenArea, bool, 7, 7, "(posX, posY, width, height, fileName, fileType) Capture a specific area of the screen")
{
    GLint positionX = dAtoi(argv[1]);
    GLint positionY = dAtoi(argv[2]);
    U32 width = dAtoi(argv[3]);
    U32 height = dAtoi(argv[4]);
    
    FileStream fStream;
    if(!fStream.open(argv[5], FileStream::Write))
    { 
        Con::printf("Failed to open file '%s'.", argv[5]);
        return false;
    }

    // Read gl pixels here
    glReadBuffer(GL_FRONT);
   
    Point2I extent;
    extent.x = width;
    extent.y = height;

    U8 * pixels = new U8[extent.x * extent.y * 4];
    glReadPixels(positionX, positionY, extent.x, extent.y, GL_RGB, GL_UNSIGNED_BYTE, pixels);

    GBitmap * bitmap = new GBitmap;
    bitmap->allocateBitmap(U32(extent.x), U32(extent.y));
   
    // flip the rows
    for(U32 y = 0; y < (U32)extent.y; y++)
        dMemcpy(bitmap->getAddress(0, extent.y - y - 1), pixels + y * extent.x * 3, U32(extent.x * 3));

    if ( dStrcmp( argv[6], "JPEG" ) == 0 )
        bitmap->writeJPEG(fStream);
    else if( dStrcmp( argv[6], "PNG" ) == 0)
        bitmap->writePNG(fStream);
    else
        bitmap->writePNG(fStream);

    fStream.close();

    delete [] pixels;
    delete bitmap;

    return true;
}

I'll let you interpret the code, which unfortunately was not commented. If there is a specific question about the code, ask away. It should also be noted that the above code only works with OpenGL applications. GBitmap is a requirement as well, which is also available in the T2D source.