Pokemon-snap camera mechanic?

I don’t want to recreate Pokemon snap but I may want a camera mechanic like it or Beyond Good & Evil. I know about the screenshot module, but there are a few things I need help with.

  1. Overwriting images by default, in case the player wants to snap the same image again. If I can put the binary image data into a variable, I can write it to a file and overwrite that file. (can it be done)

  2. post-production before saving the image (saving it as a png with compression or jpg with lower quality).

  3. Determine what objects are in the image (might be able to do it with the view frustrum).

  4. Determine size and zoom if the objects are too small or large. (could be done with getDistanceTo and some math)

I can get the main subject from a ray sensor, and use a dictionary to save the points, but I still need assistance with the other stuff.

Answer to first question:

You can store images, I would keep them in memory but not save them as image files (Writing/reading seems unnecessary).
I did something similar here: https://github.com/Kiva-Entertainment/yohk/blob/master/script/dynamicMaterial.py#L26

In your case, it should be called something like logic.pics instead of logic.textures

When your game starts/your level starts/what have you, create an empty list of pictures:

 logic.pics = []

Whenever you want to add a picture (Called “pic” in the code below) to the stored pictures, append to that list:

 logic.pics.append(pic) 

Then you have an ordered list of pictures which can be accessed easily:

 thirdPic = logic.pics[2] 
  1. Yes, I suppose you can write the files out if you need to. I would probably save the image buffer itself that you get from the camera out to a file; you should be able to load it back via the bge.texture.ImageBuff class (particularly the Load function).

Like Kiva said, you could just write it to memory if you won’t need to access it apart from the save files (with the rest of the save game data).

  1. Yes, you can. You could possibly do it with a GLSL filter before capturing the image via the bge.texture module, but you can easily loop through the color values and tweak them as necessary before saving them (either to a variable, or out to a file). Basically, it would be a filter that runs on the CPU (using Python) rather than the GPU (a GLSL shader). It’s going to be far slower than the GLSL filter, but since it’s just an image for a shot from a camera, it shouldn’t be a big deal.

  2. You could use the KX_Camera.point / sphere / boxInsideFrustum functions to tell if a specific object point / sphere / bounding box intersects, is inside of, or is outside of the view frustum. You could also create an object that mimics the camera’s view frustum, and just do a collision check with it against different objects.

  3. You try an external object that adjusts its scale as you zoom, thereby allowing you to check against it as well to see if an object is too close (i.e. if an object intersects with the “TooClose” object, then you know that it’s too close to the camera, with the zoom level set the way it is).

Thanks for the great ideas. The reason I wanted to write the images to files is that I might have 10-60 for the film roll (or sd card) and an album for the player of ~60-120 images. Each image when saved is ~2 megs, so at max that is 360 megs in ram and the save file, and thus that much slower to load/save/run. That wouldn’t be so bad if I could reduce the pix to ~500 KB (I have re-saved images using gimp and seen them go as low as ~300 KB), plus the player might want to export images and upload them to a blog. I don’t know how to write GLSL filters (unless you ar saying to just use the grayscale), plus many glsl filters reduce the framerate.

How would I loop through the colors?

I’m not sure if you’ll be able to save out to a PNG file (or other photo editor / human visible image file) using the BGE alone. Saving the data out to reload the same picture later should be easy enough, though.

You would loop through the colors by grabbing the image array from the bge.texture source. So you set it up like you’re capturing the scene, and then grab the image array from the image property. Then, loop through the values, and you can change the values, as they correspond to the RGB (and A, if you specify) components.

What about if you ran an external compressor when taking a screenshot?
Also, jpg files are generally much smaller than PNGs, as they are a lossy compressed format, if size and speed is a priority over quality.

Thank you all, the pages have been saved and I’m going to do a ton of blendering on Sunday. @MrPutuLips, I might swap to jpg for my textures too, but I dunno how getScreenshot() saves normally, or if python’s write module will write it as a jpg. (I normally use png for textures, but a 90% jpg might look more n64 nostalgic)