Saved image is empty with data loaded from ofTexture

i’m using ofxMSAOpenCL to do image processing with GPU. just playing with ofxMSAOpenCL’s image example. with
clImage[activeImageIndex].getTexture().draw(vidWidth, 200);
the texture could be drawn correctly.
now i want to load the texture data into ofImage and save it to hard disk with the following code:
void ofApp::keyPressed(int key){
if(key == 's'){
ofPixels pixels;
pixels.allocate(vidWidth, vidHeight, OF_PIXELS_RGBA);
clImage_[1].getTexture().readToPixels(pixels);
ofImage img;
string name = ofToString(ofGetFrameNum()) + ".png";
img.setFromPixels(pixels);
img.saveImage(name);
}
}
however, i always got a total blank image. does anybody know the reason?

btw, how could i retrieve the pixel value for each element in ofPixels? e.g. i want to do something like the following:
for(int i=0;i<pixels.size();i++)
std::cout<<pixels[i].getColor()<<std::endl;//compile error for pixels[i].getColor()

Hi yangyangcv,

Try this:

void ofApp::keyPressed(int key){
    if(key == 's'){
        ofImage save;
        clImage_[1].getTexture().readToPixels(save.getPixels());
        string name = ofToString(ofGetFrameNum()) + ".png";
        save.save(name);
    }
}

For the second question, you are missing the index parameter in getColor()

for(int i=0;i<pixels.size();i++)
    std::cout<<pixels.getColor(i)<<std::endl;

another thing to watch for is doing tasks on in keyPressed, you may be better off with

void ofApp::keyPressed(int key){
    if(key == 's'){
    doSave = true;
    }

and back in update or draw()

if(doSave)
{
        ofImage save;
        clImage_[1].getTexture().readToPixels(save.getPixels());
        string name = ofToString(ofGetFrameNum()) + ".png";
        save.save(name);
       doSave = false;
}

thanks for the reply man. but still now work. following is the complete code:

ofApp.h

#pragma once
#include "ofMain.h"
#include "MSAOpenCL.h"
class ofApp : public ofBaseApp{

public:
	void setup();
	void update();
	void draw();

	void keyPressed(int key);
	void keyReleased(int key);
	void mouseMoved(int x, int y );
	void mouseDragged(int x, int y, int button);
	void mousePressed(int x, int y, int button);
	void mouseReleased(int x, int y, int button);
	void mouseEntered(int x, int y);
	void mouseExited(int x, int y);
	void windowResized(int w, int h);
	void dragEvent(ofDragInfo dragInfo);
	void gotMessage(ofMessage msg);
	

	int camw_, camh_;
	ofVideoGrabber cam_;
	ofImage	img_;
	ofImage img2_,img3_;
	ofPixels resultPixels_;

	msa::OpenCL			openCL_;
	msa::OpenCLImage	clImage_[2];				// two OpenCL images
		unsigned char		*pixels_;
};

ofApp.cpp
#include “ofApp.h”

//--------------------------------------------------------------
void ofApp::setup(){
	ofBackground(0);

camw_ = 640;
camh_ = 480;
cam_.initGrabber(camw_,camh_);
img_.allocate(camw_,camh_,OF_IMAGE_COLOR);
img2_.allocate(camw_, camh_, OF_IMAGE_COLOR_ALPHA);
img3_.allocate(camw_, camh_, OF_IMAGE_COLOR_ALPHA);
pixels_ = new unsigned char[camw_*camh_*4];

openCL_.setupFromOpenGL(0);
clImage_[0].initWithTexture(camw_, camh_, GL_RGBA);
clImage_[1].initWithTexture(camw_, camh_, GL_RGBA);
openCL_.loadProgramFromFile("ImageProcessing.cl");
	openCL_.loadKernel("msa_flipx");
}

//--------------------------------------------------------------
void ofApp::update(){
	cam_.update();
	if (cam_.isFrameNew()) {
		img_.setFromPixels(cam_.getPixels());
		int pixelIdx = 0;
		for (int i = 0; i < camh_; i++) {
			for (int j = 0; j < camw_; j++) {
				int rgbIdx = 3 * pixelIdx;
				int rgbaIdx = 4 * pixelIdx;
				pixels_[rgbaIdx] = cam_.getPixels()[rgbIdx];
				pixels_[rgbaIdx+1] = cam_.getPixels()[rgbIdx+1];
				pixels_[rgbaIdx+2] = cam_.getPixels()[rgbIdx+2];
				pixels_[rgbaIdx+3] = 255;
				pixelIdx++;
			}
		}

		clImage_[0].write(pixels_);
		shared_ptr<msa::OpenCLKernel>(kernel) = openCL_.kernel("msa_flipx");
		kernel->setArg(0, clImage_[0]);
		kernel->setArg(1, clImage_[1]);
		kernel->run2D(camw_, camh_);
	}
}

//--------------------------------------------------------------
void ofApp::draw(){
	ofSetColor(255);
	img_.draw(0,0,320,240);
	openCL_.finish();
	clImage_[1].getTexture().draw(320,0,320,240);
	img2_.setFromPixels(pixels_, camw_, camh_, OF_IMAGE_COLOR_ALPHA);
	cam_.getTexture().readToPixels(img3_.getPixels());//this works
	//clImage_[1].getTexture().readToPixels(img3_.getPixels());//this just show a complete blank image
	img3_.update();
	img2_.draw(0,240,320,240);
	img3_.draw(320, 240, 320, 240);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

you are trying to save an RGBA image as a jpg which is limited to RGB only. You’ll end up with a null file. Try saving as png, that should work. For jpg, make sure the pixels and fbo are only RGB.

thanks man. i tried png with no luck.
besides, in the code i posted above, i just draw the ofImage instead of saving it. but it’s still a complete blank image :frowning:

hello,

this is how i save an image from a FBO if it helps :

ofFbo comp;
ofPixels bat;
...
comp.readToPixels(bat);
ofSaveImage(bat, "test.png");

it works for fbo but does not work for OpenCLImage :frowning:
the weird thing is,
clImage_[1].getTexture().draw(320,0,320,240);// this draw correctly
clImage_[1].getTexture().readToPixels(img3_.getPixels()); // this does not work

where clImage_[1] is just an OpenCLImage

i find the reason. if the ofImage is of the type OF_IMAGE_COLOR_ALPHA,then it cannot be saved to disk. If it’s of the type OF_IMAGE_COLOR, it can be saved. does anybody know how to convert an ofImage from OF_IMAGE_COLOR_ALPHA to OF_IMAGE_COLOR?

yes, JPG doesn’t support alpha layer.
i thought when you save an RGBA image into jpg OF would automatically convert it though…

you can specify color mode when allocating the image (ofImage or ofPixels) before using it :

img.allocate(640, 480, OF_IMAGE_COLOR);