アニメ gif が作りたくなって
なんとなくアニメ gif が出来るとうれしいなと思い立って、少し調べてみました。
以下のサイト、およびそこからリンクされているサイトをアニメを見ながら眺めること1時間。
最小サイズのgif画像とアニメーションgif – ソフトウェア開発日記
どうもデータ長を 8bit にすると、バイト単位で扱えるようになって楽な気がしたので実験してみることにしてみました。まずは静的な画像から。
実行結果
ソースプログラム
program gif use, intrinsic :: iso_fortran_env implicit none integer :: iw integer(int16) :: m, nx = 15, ny = 10 type :: t_gif_header sequence character(3) :: signature = 'GIF' character(3) :: version = '89a' ! '87a' integer(int16) :: width integer(int16) :: height integer(int8) :: pck = int(B'10001001', int8) integer(int8) :: background_color_index = 0 integer(int8) :: pixel_aspect_ratio = 0 end type integer(int8), allocatable :: global_color_table(:) type (t_gif_header) :: head type :: t_image_block sequence integer(int8) :: image_separator = Z'2C' integer(int16) :: image_left_position = 00 integer(int16) :: image_top_position = 00 integer(int16) :: image_width integer(int16) :: image_height integer(int8) :: pck = int(B'00000000', int8) ! local color table !integer(int8) :: LZW_minimum_code_size !integer(int8) :: block_size = !integer(int8) :: image_data !integer(int8) :: block_terminator = Z'00' end type t_image_block type (t_image_block) :: img integer, allocatable :: ipattern(:) ! ! open(newunit = iw, file = 'test.bin', access = 'stream') open(newunit = iw, file = 'test.gif', access = 'stream') head%width = nx head%height = ny img%image_width = nx img%image_height = ny ! allocate(global_color_table(3 * 128)) ! 128? global_color_table = 0 global_color_table = int([0,0,0,255, 0, 0, 0,255,0, 0,0,255], int8) ! RGB write(iw) head write(iw) global_color_table ! ipattern = [01, 01, 01, 01, 01, 02, 02, 02, 02, 02, 03, 03, 03, 03, 03] ! RGB ! write(iw) img write(iw) achar([07, 152]) ! 7+1 bit ~ 128 color, 152 data (150 RGB + 2 clear) write(iw) achar([ipattern, ipattern]) write(iw) achar([ipattern, ipattern]) write(iw) achar([ipattern, ipattern]) write(iw) achar([ipattern, ipattern]) write(iw) achar([128]) ! clear dictionary ? write(iw) achar([ipattern, ipattern]) write(iw) achar([128]) ! clear dictionary ? write(iw) achar(00) ! block_terminator write(iw) achar(int(Z'3B')) end program gif
データ 4bit 単位 8色
データ単位が 4bit なら2ピクセルで 1byte になるので分かりやすいはず。
実行結果
ソースプログラム
バイト内のオーダーが逆っぽいのが謎??勘違いしている?下位ビットから読む?
program gif use, intrinsic :: iso_fortran_env implicit none integer :: iw integer(int16) :: m, nx = 10, ny = 10 type :: t_gif_header sequence character(3) :: signature = 'GIF' character(3) :: version = '89a' ! '87a' integer(int16) :: width integer(int16) :: height integer(int8) :: pck = int(B'10001001', int8) integer(int8) :: background_color_index = 0 integer(int8) :: pixel_aspect_ratio = 0 end type integer(int8), allocatable :: global_color_table(:) type (t_gif_header) :: head type :: t_image_block sequence integer(int8) :: image_separator = Z'2C' integer(int16) :: image_left_position = 00 integer(int16) :: image_top_position = 00 integer(int16) :: image_width integer(int16) :: image_height integer(int8) :: pck = int(B'00000000', int8) ! local color table end type t_image_block type (t_image_block) :: img ! open(newunit = iw, file = 'test.gif', access = 'stream') head%width = nx head%height = ny img%image_width = nx img%image_height = ny ! allocate(global_color_table(3 * 8)) ! 8? global_color_table = 0 global_color_table = int([0,0,0,255, 0, 0, 0,255,0, 0,0,255], int8) ! RGB write(iw) head write(iw) global_color_table ! write(iw) img write(iw) achar([03, 60]) ! 3+1 bit ~ 8 color, 60 byte (100 RGB + 20 clear) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar([Z'21', Z'13', Z'32', Z'18', Z'32', Z'81']) write(iw) achar(00) ! block_terminator write(iw) achar(int(Z'3B')) end program gif