openFrameworksで背景を透明化したPNG画像を書き出す方法。
標準のライブラリだけでは上手いこと書き出せなかったので
イメージピクセルにアクセスして、アルファ値を変更して画像保存した。
簡単に書くと
・イメージ宣言の際にOF_IMAGE_COLOR_ALPHAを代入
・pixels宣言でwidth*height*4
・getPixels()
・アルファ値[(widthOfLine * y + x )* 4 + 3]
・setFromPixels → saveImage
ベースとなるサンプルはimageSaverExampleを使うと良い。
・ キャプチャ用イメージとアルファ変更用イメージのサイズを宣言。
この時OF_IMAGE_COLOR_ALPHAを代入しておく。
・これはビデオイメージから白い部分を判別し、透過させ書き出している。
・ピクセルに対しての変更は以下を参考にする。
RGBAがBGRAになっているので格納の際に逆にすると良い。
・alpha値は0〜255で透明〜不透明になっている。100くらいだと半透明で保存できる。
標準のライブラリだけでは上手いこと書き出せなかったので
イメージピクセルにアクセスして、アルファ値を変更して画像保存した。
簡単に書くと
・イメージ宣言の際にOF_IMAGE_COLOR_ALPHAを代入
・pixels宣言でwidth*height*4
・getPixels()
・アルファ値[(widthOfLine * y + x )* 4 + 3]
・setFromPixels → saveImage
ベースとなるサンプルはimageSaverExampleを使うと良い。
void testApp::setup(){
〜
img.allocate(300,300,OF_IMAGE_COLOR_ALPHA);
img2.allocate(300,300,OF_IMAGE_COLOR_ALPHA);
・ キャプチャ用イメージとアルファ変更用イメージのサイズを宣言。
この時OF_IMAGE_COLOR_ALPHAを代入しておく。
void testApp::draw(){
if(bSnapshot2 == false){
ofSetColor(0xffffff);colorImg.draw(20,20);//元画像
}
if(bSnapshot2 == true){
ofEnableAlphaBlending();
ofSetColor(0xffffff);
img2.draw(200,200);//アルファ変更画像
ofDisableAlphaBlending();
}
//保存
if (bSnapshot2 == true){
char fileName[255];
sprintf(fileName, "snapshot_%0.3i.png", snapCounter);
img2.saveImage(fileName);
sprintf(snapString, "saved %s", fileName);
bSnapshot2 = false;
}
if (bSnapshot == true){
img.grabScreen(200,200,300,300);
unsigned char * pixels;
unsigned char * pixels2;
pixels = (unsigned char*)malloc(300*300*4);
pixels2 = (unsigned char*)malloc(300*300*4);
pixels = img.getPixels();
int widthOfLine = 300; // 画像の幅
for (int y = 0; y < 300; y++) {
for (int x = 0; x < 300; x++) {
int red = pixels[(widthOfLine * y + x) * 4];
int green = pixels[(widthOfLine * y + x )* 4 + 1];
int blue = pixels[(widthOfLine * y + x )* 4 + 2];
pixels2[(widthOfLine * y + x) * 4] = blue;
pixels2[(widthOfLine * y + x) * 4 + 1] = green;
pixels2[(widthOfLine * y + x )* 4 + 2] = red;
if(red > 150 && green > 150 && blue > 150){
pixels2[(widthOfLine * y + x )* 4 + 3] = 0;//アルファを変更
}else{ pixels2[(widthOfLine * y + x )* 4 + 3] = 255;}
}
}
img2.setFromPixels(pixels2, 300, 300, OF_IMAGE_COLOR_ALPHA);//アルファ用に格納
snapCounter++;
bSnapshot = false;
bSnapshot2 = true;
}
・これはビデオイメージから白い部分を判別し、透過させ書き出している。
・ピクセルに対しての変更は以下を参考にする。
RGBAがBGRAになっているので格納の際に逆にすると良い。
pixels[(widthOfLine * y + x) * 4] = red;・あとはOF_IMAGE_COLOR_ALPHAをGL_RGBAにしないこと。
pixels[(widthOfLine * y + x) * 4 + 1] = green;
pixels[(widthOfLine * y + x )* 4 + 2] = blue;
pixels[(widthOfLine * y + x )* 4 + 3] = alpha;
・alpha値は0〜255で透明〜不透明になっている。100くらいだと半透明で保存できる。