Erasing an Image

Hey ,

I have an image (.png) whose pixels I want to erase. And when it is erased (or when all the pixels are gone) , I want an interaction to happen (like a video, image appearing).

I have tried all examples related to alphamasking and fbo’s , but all of then just end up manipulating the masked layer ( which does not allow me to make interactions when the erasing is done).

Could anyone guide me in what direction/steps do I take for such an interaction ?

Hello!

Not really sure if I understood well your question but… If you get direct access to the pixels of the Image… there you could manipulate them directly, isn’t?

Check this out:

void ofApp::setSomePixelsBlack() {
	for (int i = 0; i < (myPngImage.getWidth() * myPngImage.getHeight()) * 3; i += 3) {
		if (ofRandom(0,1) > 0.4) {
			myPngImage.getPixels()[i + 0] = 0;
			myPngImage.getPixels()[i + 1] = 0;
			myPngImage.getPixels()[i + 2] = 0;
		}
	}
	myPngImage.update();
}

Common mistake is to forget to update your changes after pixels modifications over the image.

Cheers!

1 Like

Also, there is an excellent resource to learn how to manipulate images pixel by pixel. It starts from the basic but it gives you enough material to get your hand dirty with computer vision concepts.

http://openframeworks.cc/ofBook/chapters/image_processing_computer_vision.html

This is the code i’m using. It is basically giving the pixel in the image a white colour (an alternative to erasing).
I now want to activate something when all the pixels turn white . But for some reason it is only working with big images. Im using count to calculate the number of white pixels. Anyone know whats goin wrong?

void ofApp::update() {


ofPixels & pixels = img.getPixels();

if ((ofGetMousePressed(OF_MOUSE_BUTTON_LEFT))) {  // If the left mouse button is pressed...

	for (int i = -30; i < 30; i++) {
		for (int j = -30; j < 30; j++) {

			pixels.setColor(ofGetMouseX() + i, ofGetMouseY() + j, ofColor::white);//place your pixels

		}
	}

	int count = 0;
	int w = img.getWidth();
	int h = img.getHeight();

	for (int k = 0; k < w; k++) {
		for (int l = 0; l < h; l++) {

			if (pixels[l*w + k] > 251) {
				count++;
			}
		}
	}
	img.update();
	cout << "Value id" << count << endl;
}

}

Hello !

Is it your image RGB or GrayScale? If it’s RGB then you will need to check that R,G,B values.
All pixels follows this order RGB, RGB, RGB … until w * h * 3.

for RGB try something like this:

int threshold = 251;
int count = 0;
bool bAllWhite = false;

    	for (int i = 0; i < w*h*3; i=i+3) {
    			if (pixels[i]> threshold && pixels[i+1] > threshold && pixels[i+2]> threshold ) {
    				count++;
    		}
    	}

if(count == w*h*3){
     bAllWhite  = true;
}

You might find all this info as Edapx commented in that chapter of the the ofBook but as a Tip for direct pixel manipulation it’s much more easy to use ofxOpencv images ( like ofxCvColorImage or ofxCvGrayScaleImage) and not with ofImage ( apologies I point your wrongly before )

Check this loop for ofxCvColorImage:

		////Set random pixels to white
		for (int i = 0; i < colorImage.getWidth()*colorImage.getHeight()*3; i=i+3) {
			float randomIdPixel = ofRandom(0, 1);
		    if (randomIdPixel < 0.5) {
				colorImage.getPixels()[i] = 255; //R
                colorImage.getPixels()[i+1] = 255; //G 
                colorImage.getPixels()[i+2] = 255; // B
			}
		}

or for a ofxGrayScaleImage :

		//Set some pixels to white
		for (int i = 0; i < grayImage.getWidth()*grayImage.getHeight(); i++) {
			float randomIdPixel = ofRandom(0, 1);
			if (randomIdPixel < 0.5) {
				grayImage.getPixels()[i] = 255;
			}
		}

Also I’ve seen there is this function to set all pixels inside in a speficif colore just in one line of colde.

Hope that helps!