Most friendly way to take a mobile screen grab?

Hi all,

I was wondering what people would suggest as to the best way to save a portion of the current screen (a rectangular section of pixels).

For example, I paint a range of rectangles, circles and random images to the canvas. When I press a key, it takes a snapshot of a portion of the screen. What is the best way to grab the data?

Would the following work?

DirectGraphics dgSrc = DirectUtils.getDirectGraphics(g);
short[] pixels = new short[nPixels];
dgSrc.getPixels(pixels,0,w,0,0,w,h,DirectGraphics.TYPE_USHORT_444_RGB);

If your code is properly structured, all you would need to do is create an offscreen image, get a Graphics context to it, and pass it into paint(…).

I can now confirm that this method works, and works very well at that. Very fast with no obvious impression on additional heap space requirements.

I’ve also been trying to use TYPE_BYTE_8_GRAY, TYPE_BYTE_332_RGB… but I get illegal argument exceptions. Could anyone list the TYPEs which are accepted by recent nokia devices (or point me in the direction of where I can find some info on this).

The 4444 and 8888 formats are the most common on the Nokia color phones. I still haven’t seen a color model that didn’t support 4444.
Using the phones native format (DirectGraphics.getNativePixelFormat()) will give you the best performance as no conversions will be needed.

shmoove

I ask again - why do you want to grab pixel data from the screen.

Why not just redraw the state of the current screen, to your own back buffer?

It is a far more portable, and infact far more reliable way of doing a screen capture.

Even using J2SE, this is how you should do screen captures!

“I ask again - why do you want to grab pixel data from the screen.” - because I need access to the pixel data to store into an RMS as an array or shorts.

I’m using 444 RGB (rather than 4444) because I want to try and store as little information in the RMS as possible. Does it sound like i’m going through the right routes?

Your feedback has been much appreciated!

hmm, 12x128x128/8 /1024.

A screenshot on a series 40 will take up 24kb (assuming you arn’t going to compress it)

Could you not store, and recall the current state of the program (for the screenshot), and use less than 24kb?

Abuse - I actually have a system that saves the state of all the environment and graphic object variables (user objects, swarm data, and other user data) - serialized to an RMS. I’m having to test the pixel data method as the application I’m building is updateable via a network. Users can download screengrabbed data objects, but going the state-based route - could potentially require a large number of other sprites to be stored on the device. If the object is based on pixel data, the user will just need to download this and the network system would not need to check for any additional graphics to download.

Or maybe I’m just lazy? Or not confident enough with the stability of httpConnections? But you’re right - image pixel data can potentially consume a large amount of space in the RMS.

Another option (how doable this is depends on how these images are created) that could potentially save you a ton of space would be to store the images procedurally a la vector-graphics. You said the image is just a bunch of circles and rectangles and lines, so you could store it as a bunch of instructions so that it can be reproduced (store each shape as a bunch of vertices+color info+fill or outline+brush style, and each image as an ordered series of shapes). This would mean that you would need to keep track of things while the users are drawing the images though.

shmoove

Thanks for the idea Shmoove! Unfortunately, I’ve got lots of lovely little pixel graphics. The circles and squares were just an attempt to simplfy my attempt at describing my situation.

Ok, now that I’ve got a screen capture system to compare to my state-based system - I can now weight up the positives and negatives of both…

…I’m quickly coming to the conclusion that using TYPE_USHORT_444_RGB takes too much space. Has anyone used TYPE_BYTE types with Nokia devices? If so, which ones? If I can use a byte array instead, the pixelgrab technique would just about win me over.

Many thanks.

Have you tried adding compression?

If you can accept a lossy screenshot (as I assume you can if you are considering TYPE_BYTE for the pixel format), you should be able to get a 24k screenshot down to around 2-4k.

“Have you tried adding compression?” - Not yet, what’s the best way to tackle this? I could encode my own gif-based algorithm, but I’d rather not re-invent the wheel. Any tips on compression?

Many thanks for all the feedback!

I’d just google for a jpg implementation.

Although, it’ll probably use floats :expressionless:

You may have trouble finding 1 based on fixed point only.