1x1pxのgifのjavaでの作成の覚書
2007/9/14
概要
1x1pxの赤gifファイルを作成します。 もっとも簡単なgifファイルの確認ですので, LZWアルゴリズムはプログラムには含まれていません。 iamge dataは机上で計算して作成しました。
コンパイル
$ javac mkgif.java
実行
$ java mkgif
ソース
ソースコードのファイル名はmkgif.javaです。
// mkgif import java.io.*; class mkgif { public static void main(String[] args) { try { // header byte[] signature = {0x47, 0x49, 0x46}; // GIF byte[] version = {0x38, 0x39, 0x61}; // 89a // logical screen descriptor // 横幅=1px, リトルエンディアン byte[] screen_width = {0x01, 0x00}; // 縦幅=1px, リトルエンディアン byte[] screen_height = {0x01, 0x00}; byte[] screen_pack = new byte[1]; int gct_flag = 0x80; // gct=global color table int color_resolution = 0x00; // ここには色の指定(global color tableへのインデックス)に // 必要なbit数-1を設定する。 // 赤だけなので1bitあればいいから0を設定 int sort_flag = 0x00; // global table is not sorted. int size_of_gct = 0x00; screen_pack[0] = (byte)(gct_flag | color_resolution | sort_flag | size_of_gct); byte[] background_color_index = {0x01}; byte[] pixel_aspect_ratio = {0x00}; // * 縦横比は設定しない。 // global color table byte[] global_color_table = { -0x01, 0x00, 0x00, // * RGB順, -0x01=0xff(ややこしい!) 0x00, 0x00, 0x00 }; // image descriptor byte[] image_separator = {0x2c}; byte[] image_left_pos = {0x00, 0x00}; byte[] image_top_pos = {0x00, 0x00}; byte[] image_width = {0x01, 0x00}; byte[] image_height = {0x01, 0x00}; byte[] image_pack = new byte[1]; // int local_color_table_flag = 0; // int interlace_flag = 0; // int sort_flag = 0; // int reserverd = 0; // int size_of_lct = 0; image_pack[0] = 0x00; // table based image data byte[] lzw_minimum_code_size = {0x02}; // 一色なので1bitでいいのだが, // 実装の都合上(?), 最低値が2(?) // lzw_minimum_code_sizeから // clear_codeは 100 // したがって, 終了コードは101 // したがって, 全体のコードは // 100...101となる。 // clear_codeの直後は左上の画素の色の指定。 // global color tableの0番目をここでは指定 // するので, 0。ビット数を圧縮コードの長さ, // ここではlzw_minimum_code_size+1=3bitに // 合わせるので000にする。 // 先のclear_code, 終了コードとあわせて, // 100 000 101 // これを8bitづつにパックする。 // 圧縮コードは左から右のまま, 右詰で // つめていく(あぁ, ややこしい) // 最初のclear_codeを設置 // xxxxx100 // インデックスを追加 // xx000100 // 終了コードを追加, 先頭の1bitがあまるが, // それは2バイト目に右詰で追加。 // 01000100 xxxxxxx1 // 終わったので, 残りの未設定の部分を // 0で埋める。 // 01000100 00000001 byte[] block_size = {0x02}; byte[] data_values = {0x44, 0x01}; // block terminator byte[] block_terminator = {0x00}; // trailer byte[] trailer = {0x3b}; // 固定 // ファイルへの書き込み // 準備 File fp = new File("red.gif"); fp.createNewFile(); // 存在していた場合がないが... FileOutputStream fs = new FileOutputStream(fp); // 書き込んで行きましょう。 fs.write(signature); fs.write(version); fs.write(screen_width); fs.write(screen_height); fs.write(screen_pack); fs.write(background_color_index); fs.write(pixel_aspect_ratio); fs.write(global_color_table); // image descriptor fs.write(image_separator); fs.write(image_left_pos); fs.write(image_top_pos); fs.write(image_width); fs.write(image_height); fs.write(image_pack); fs.write(lzw_minimum_code_size); fs.write(block_size); fs.write(data_values); fs.write(block_terminator); fs.write(trailer); // 書き込み終了 fs.close(); } catch(Exception e) {} } // main } // /mkgif
参考