[C++] 239 FLTK : Fl_Boxに高さ不足の画像を表示した際の座標 アスペクト比

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 3.8.1, NO IDE]

Fl_Boxに高さ不足の画像を表示した際、画像の左上を原点(0, 0)とするための調整が少しややこしかったので書き留めておきます。

横幅が一致していて高さが足りない画像の場合はその縦位置は適当に置かれているわけではなく、残った空白がアスペクト比で配分されていました。幾何学の世界ですね。

今回はアスペクト比が4:3なので、縦の空白は上部:下部 = 3:4になっています。これにより画像の左上Y座標をゼロにするための調整値が算出できます。

Fl_PNG_Image *png = new Fl_PNG_Image((paths[0]).c_str());
anaW = wInput -> value();
anaH = hInput -> value();

aspect = stof(string(anaW))/stof(string(anaH));

if (aspect > 4/3){
    newH = stof(string(anaH)) * 480/stof(string(anaW));
    cout << "newH: " << newH << endl;
    png_copy = png -> copy(480,round(newH));

    // Y調整値算出
    adjY = round((360 - newH) * 3/7);

} else {
    newW = stof(string(anaW)) * 360/stof(string(anaH));
    cout << "newW: " << newW << endl;
    png_copy = png -> copy(round(newW),360);
}

showBox -> image(png_copy);
showBox -> redraw();

[C++] 238 FLTK : アスペクト比固定、小数点以下の扱い

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 3.8.1, NO IDE]

動画編集アプリの左下に画像をコマ送りで表示させるのですが、アスペクト比を元動画のままにして、経過時間を小数点第3位までとしました。

floatは有効桁数が7桁なので小数点以下で四捨五入しても、1.570000のような表示になります。そこでfloatを文字列に変換し、無限ループを利用して末尾が0である限り削除し続けるようにしました。

ただこの方法では小数点以下の桁数を固定できないのがデメリットです。Pythonであれば簡単に桁数を揃えられそうですが、C++は面倒なので最小限の手立てに留めておきます。

void showCB(Fl_Widget*, void*) {
    paths = getFilePath("/Volumes/DATA_m1/VideoEditor/images", "png");
    // スライダーの数値を取得
    slider -> bounds(0, (double)(paths.size() -1));

    showData(fpsFile);
    fpsChar = fpsInput -> value();
    if (fpsChar == NULL){
        return;
    }

    string fpsStr = string(fpsChar);
    sec = frameNum/stof(fpsStr);
    sec2 = round(sec*1000)/1000;
    sec2_str = to_string(sec2);

    while(1){
        if (sec2_str.back() == '0' or sec2_str == "0."){
            sec2_str.pop_back();
        } else {
            break;
        }
    }
    imageSec -> value(sec2_str.c_str());

    imageNumStr = to_string(frameNum +1) + "/" + to_string(paths.size());
    imageNum -> value(imageNumStr.c_str());

    Fl_PNG_Image *png = new Fl_PNG_Image((paths[0]).c_str());
    anaW = wInput -> value();
    anaH = hInput -> value();

    aspect = stof(string(anaW))/stof(string(anaH));

    if (aspect > 4/3){
        newH = stof(string(anaH)) * 480/stof(string(anaW));
        cout << "newH: " << newH << endl;
        png_copy = png -> copy(480,round(newH));
    } else {
        newW = stof(string(anaW)) * 360/stof(string(anaH));
        cout << "newW: " << newW << endl;
        png_copy = png -> copy(round(newW),360);
    }

    showBox -> image(png_copy);
    showBox -> redraw();
}