How to save image output

Hello all,

This is a simple project to extract Google Street View to a panorama image.

It works fine and the result (pano image of Trump Tower street) looks good, but I just don’t know how to save the output. Think the code is missing the saving part.

Can anyone help me out how to save the resulting image?
Or correct me if I am missing anything.

Thank you,

hey @Sunny,

on the above app (notice that this is not an addon even it’s “wrong” named as ofx),
image it’s an ofFbo, not an ofImage/ofTexture, so you need to add some code to save the image snapshot to the disk (bin/data)

Add this code to save a snapshot when pressing the space key.

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
	if (key == ' ')
	{
		ofImageQualityType quality = OF_IMAGE_QUALITY_BEST;
		ofPixels pix;
		pix.allocate(image.getWidth(), image.getHeight(), OF_IMAGE_QUALITY_BEST);
		image.readToPixels(pix);
		ofSaveImage(pix, "mySnapshot.png");
	}
}

You can learn on the examples how to handle images like in this example:
openFrameworks\examples\input_output\imageSaverExample\

1 Like

just to learning purposes…
you can also save the raw source google image (just received) without processing here. Or to check where the code makes the pano composition building…

    if (response.status == 200) {
        if (ofIsStringInString(response.request.name, "TILE")) {
            vector<string> split = ofSplitString(response.request.name, "_");
            ofImage im;
            im.load(response.data);
            PanoTile tile;
            tile.x = ofToInt(split[1]);
            tile.y = ofToInt(split[2]);
            tile.image = im;
            panoTiles.push_back(tile);

            // ->

            ofSaveImage(im, "mySnapshot.png");
        }
    }
1 Like

Thanks for the last help, it worked on regular images.
But for the below code(main part), which is creating a depth map from Google street view, I still am not sure how to save. If I add the same as moebiussurfing showed me, the identifier “image” is undefined.

void ofApp::decodeDepthMap() {
string depth_map_base64 = “00”;

vector<unsigned char> depth_map_compressed(depth_map_base64.length());
int compressed_length = decode_base64(&depth_map_compressed[0], &depth_map_base64[0]);

//Uncompress data with zlib
//TODO: decompress in a loop so we can accept any size
unsigned long length = 512 * 256 + 5000;
vector<unsigned char> depth_map(length);
int zlib_return = uncompress(&depth_map[0], &length, &depth_map_compressed[0], compressed_length);
if (zlib_return != Z_OK) {
    cout << "unable to decompress depthmap" << endl;
    return;
}

//Load standard data
int headersize = depth_map[0];
int numberofplanes = depth_map[1] | (depth_map[2] << 8);
int mapwidth = depth_map[3] | (depth_map[4] << 8);
int mapheight = depth_map[5] | (depth_map[6] << 8);
int offset = depth_map[7];

if (headersize != 8 || offset != 8) {
    cout << "Unexpected depth map header " << endl;
    return;
}

//the values in this vector correspondent to a planeId this pixel belongs to
//depthMapIndices
vector <unsigned char> depthmapIndices = vector<unsigned char>(mapheight * mapwidth);
memcpy(&depthmapIndices[0], &depth_map[offset], mapheight * mapwidth);

 //depthMapPlanes
vector<DepthMapPlane> depthmapPlanes = vector<DepthMapPlane>(numberofplanes);
memcpy(&depthmapPlanes[0], &depth_map[offset + mapheight * mapwidth], numberofplanes * sizeof(struct DepthMapPlane));

constructDeptMap(mapwidth, mapheight, depthmapIndices, depthmapPlanes);

}

void ofApp::constructDeptMap(int width, int height, vector depthmapIndices, vector depthmapPlanes) {

vector<float> depthmap;
depthmap.clear();
depthmap.resize(width * height);

for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {

        float xnormalize = (width - x - 1.0f) / (width - 1.0f);
        float ynormalize = (height - y - 1.0f) / (height - 1.0f);

        float theta = xnormalize * (2 * PI) + (PI / 2);
        float phi = ynormalize * PI;

        //convert from spherical to cartesian coordinates
        vector<float> v;
        v.resize(3);
        v[0] = sin(phi) * cos(theta);
        v[1] = sin(phi) * sin(theta);
        v[2] = cos(phi);

        int planeIdx = depthmapIndices[y * width + x];

        if (planeIdx > 0) {
            DepthMapPlane plane = depthmapPlanes[planeIdx];
            float t = abs(plane.d / (v[0] * plane.x + v[1] * plane.y + v[2] * plane.z));
            depthmap[y * width + (width - x - 1)] = t;
        }
        else {
            depthmap[y * width + (width - x - 1)] = 0.0f;
        }
    }
}

ofPixels depthPixels;
depthPixels.allocate(width, height, 1);

for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
        float c = depthmap[y * width + x] / 100 * 255;
        depthPixels[y * width + x] = c;
    }
}

depthmapimage.setFromPixels(depthPixels);

}