FLTK 1.3.4-1 부터 좀 더 강력 해 진 영역이 있다면, 바로 Offscreen surface 에 특정 FLTK widget 을 그려 이것을 Fl_RGB_Image 로 만들 수 있다는 것 입니다.
그래서 아래 처럼 빨간 점선 안의 특정 영역 (Fl_Group* grpViewer 영역) 을 Fl_RGB_Image 로 만들고, 이를 fl_smimg 를 이용하여 burred 된 이미지로 간단히 만들 수 있습니다.
21세기 셜록인 역시 이분! 컴버배치!
▼
이 방법은 다음과 같은 원리로 진행 됩니다. (필요 사항, fl_smimg)
bool Fl_GroupAniSwitch::generate_blurred_img( Fl_Group* src, Fl_RGB_Image* &dst )
{
if ( src != NULL )
{
Fl_Image_Surface* imgsurf = new Fl_Image_Surface( src->w(), src->h(), 0 );
if ( imgsurf != NULL )
{
imgsurf->set_current();
imgsurf->draw( src );
Fl_RGB_Image* tmpimg = imgsurf->image();
Fl_Display_Device::display_device()->set_current();
if ( tmpimg != NULL )
{
⁄⁄ Make it blurred ...
int rsw = tmpimg->w() ⁄ 10;
int rsh = src->h() ⁄ 10;
if ( rsw < 1 )
rsw = 1;
if ( rsh < 1 )
rsw = 1;
BilinearFilter* filterBL = new BilinearFilter();
ResizeEngine* rse1 = new ResizeEngine( filterBL );
Fl_RGB_Image* smimg = rse1->scale( tmpimg, rsw, rsh );
delete rse1;
delete filterBL;
if ( smimg != NULL )
{
BicubicFilter* filterBC = new BicubicFilter();
ResizeEngine* rse2 = new ResizeEngine( filterBC );
dst = rse2->scale( smimg, src->w(), src->h() );
discard_rgb_image( smimg );
delete rse2;
delete filterBC;
}
discard_rgb_image( tmpimg );
}
delete imgsurf;
if ( dst != NULL )
return true;
}
}
return false;
}
void Fl_GroupAniSwitch::discard_rgb_image( Fl_RGB_Image* &img )
{
if( img != NULL )
{
if ( ( img->array != NULL ) && ( img->alloc_array == 0 ) )
{
delete[] img->array;
}
delete img;
img = NULL;
}
}
위 코드를 보면, BiLinear 로 이미지를 10% 크기로 줄인다음, 이를 다시 원래 이미지 크기로 BiCubic 을 이용해서 늘립니다. 물론 이런 경우 Gaussian 보단 빠르지만 품질은 약간 떨어 지게 되는 단점이 있지만, GUI 내에서 빠르게 배경 이미지로 뭔가를 구현 하는데 있어서는 나쁘지 않은 결과물을 얻을 수 있습니다.
여기서 주목해야 하는 것은 Fl_Image_Surface 라는 FLTK widget 을 Fl_RGB_Image 에 그릴 수 있는 offscreen render 방법 입니다. 간단한 방법으로 여러 응용을 할 수 있으며, 현재 그려지는 윈도우 전체를 blur 된 이미지로 처리하고, 이 위에 다른걸 그리는 방법을 생각 해 보는 아이디어를 구현할 수 있습니다.
마침 가칭 Fl_GroupAniSwitch() 의 메모리 누수가 해결 되었으므로, 이를 다음 post 로 올려 공개 해 보도록 하겠습니다.