AA to PNG

GD によるグラフィックスの操作

最新の xgawk では GD による簡単なグラフィック操作が可能になっています。 まだサポートしている操作は多くありませんが、awk でグラフィックスも操作できる時代になりました。

ここでは日本独自の文化でもある MS P ゴシックの幅が必要となる AA を IPA mona Font を用いて、テキストではなくグラフィックスとして PNG 画像出力を行なうものを紹介しています。

aa2image.awk

#! /usr/local/bin/xgawk -f

@load gd

#---------------------------------------------------------------------
# aa2image.awk - AAテキストファイルから画像ファイルへ変換

# グローバル変数(エラー処理用)
RETVAL = 0;
LAST_FUNCNAME = "";

BEGIN {
    # コマンドライン引数のエラーチェック
    check_args();

    # 初期化
    textfile = ARGV[1];
    color_name = ARGV[2];
    ARGV[2] = "";
    fontname = "/PATH/TO/ipagp-mona.ttf";
    coeff = 20;       # 行送り係数
    coord["x"] = 0;   # 基点座標x
    coord["y"] = 0;   # 基点座標y

    # wc コマンドで行数とファイル中の行の最大長を取得
    wc = "/usr/bin/wc -l -L ";
    while ((wc textfile | getline wc_info) > 0) {
        split(wc_info, wc_ary);
        lines = wc_ary[1];
        max_line_length = wc_ary[2];
    }

    # 白紙イメージファイルのイメージハンドラを取得
    im = get_image_handler(get_canvas(lines, max_line_length, coeff, coord));

    # 指定したカラー名から RGB 値を取得
    color = get_color(im, color_name);
}


#---------------------------------------------------------------------
# MAIN - テキストファイル読み込み
{
    # テキストをイメージに変換
    aa_text = $0
    if ((res = gdImageStringFT(im, brect, color, fontname, 12, \
               0, coord["x"], coord["y"]+coeff*NR, aa_text)) != "") {
        RETVAL = 3;
        check_error(RETVAL, "cannot draw text " res);
    }
}


END {
    # イメージファイル作成
    if (im != "") {
        output_imagefile = "aa2image.png";
        if ((res = gdImagePngName(im, output_imagefile)) == -1) {
            RETVAL = 4;
        }
        gdImageDestroy(im);
        check_error(RETVAL, "cannot make file " res);
    }
}


#---------------------------------------------------------------------
# get_canvas - 最適サイズのキャンバス(画像ファイル)と座標位置を取得
function get_canvas(lines, max_line_length, coeff, coord,    \
                    canvas, max_lines, max_length) {

    if (lines <= 12 && max_line_length <= 80) {
        canvas = "img_canvas320x240.png";
        max_lines = 12;
        max_length = 80;
    } else if (lines <= 18 && max_line_length <= 120) {
        canvas = "img_canvas480x360.png";
        max_lines = 18;
        max_length = 120;
    } else {
        canvas = "img_canvas720x540.png";
        max_lines = 27;
        max_length = 180;
    }

    # 基点となるy座標を取得
    if (max_lines > lines) {
        coord["y"] = (max_lines - lines - 1) * coeff / 2;
    } else {
        coord["y"] = 0;
    }
    
    # 基点となるx座標を取得
    if (max_length > max_line_length) {
        coord["x"] = max_length - max_line_length;
    } else {
        coord["x"] = 0;
    }

    return canvas;
}


#---------------------------------------------------------------------
# get_image_handler - イメージハンドラを取得
function get_image_handler(imagefile) {

    LAST_FUNCNAME="get_image_handler";

    im = gdImageCreateFromFile(imagefile);
    if (im == "") {
        RETVAL = 2;
    }

    check_error(RETVAL, "cannot open " imagefile);
    return im;
}


#---------------------------------------------------------------------
# get_color - カラーマップを作成、デフォルトは青色
function get_color(im, color_name) {

    color_map["white"]  = gdImageColorAllocate(im, 255,255,255);
    color_map["black"]  = gdImageColorAllocate(im, 0, 0, 0);
    color_map["green"]  = gdImageColorAllocate(im, 0, 128, 0);
    color_map["blue"]   = gdImageColorAllocate(im, 0, 0, 255);
    color_map["red"]    = gdImageColorAllocate(im, 255, 0, 0);
    color_map["yellow"] = gdImageColorAllocate(im, 255, 255, 0);
    color_map["purple"] = gdImageColorAllocate(im, 128, 0, 128);
    color_map["orange"] = gdImageColorAllocate(im, 255, 165, 0);

    if (color_name in color_map) {
        color = color_map[color_name];
    } else {
        color = color_map["blue"];
    }

    return color;
}


#---------------------------------------------------------------------
# check_args - コマンドライン引数チェック
function check_args() {

    LAST_FUNCNAME = "check_args";

    if (ARGC != 2 && ARGC != 3) {
        RETVAL = 1;
    } else {
        if (ARGC == 3 && ARGV[2] !~ /white|black|green|blue|red|yellow|purple|orange/) {
            RETVAL = 1;
        }
    }
    check_error(RETVAL, "aa2image.awk text_file [color]");
}


#---------------------------------------------------------------------
# check_error - エラーチェック
function check_error(retval, errmsg) {

    switch(retval) {
        case 0:
            return;
        default:
            if (im != "") {
                gdImageDestroy(im);
            }
    }
    printf("Error : %s : %s\n", LAST_FUNCNAME, errmsg);
    exit 1;
}

実行結果

aa2png.jpg

aa2png_caca.jpg