LSI Jiu-Jitsu

電子工作とブラジリアン柔術

OLED 0.96インチで遊ぶ (3) - PBMファイル表示

またまた久しぶりの投稿です(笑)
OLEDについて纏めたネタが色々あるので少しづつ上げていこうと思います。

今回は画像ファイルを表示する方法について紹介します。

任意の画像をGIMPで128x64にリサイズして、PBMフォーマットにエクスポートします。

f:id:mohran:20180521230445j:plain

フォーマット指定はASCIIにします。
f:id:mohran:20180521230839j:plain

こんな感じのスクリプトを通して変換→表示を行いました。
(画素値を128x64の配列に取り込んで、縦8列を1Byteにしてラスター順に出力しています)

#!/usr/bin/perl -w

open(RFP, "<" . $ARGV[0]) || die("Fatal : Can't open file ... $ARGV[0]\n");

@pbm = ();

$w = 0;
$h = 0;
$i = 0;
while(<RFP>){
  $l = $_;
  chomp($l);

  $l =~ s/#.*$//;

  if($l eq ''){ next; }

  $i++;
  if($i==1){
    if($l ne 'P1'){ die("Error : It isn't P1 format ...\n"); }
  }elsif($i==2){
    ($width, $height) = split(/\s+/, $l);
  }else{
    foreach $d (split(//, $l)){
      $pbm[$h][$w] = $d; 
      $w++;
      if($w==$width){
        $h++;
        $w = 0;
      }
    }
  }
}
close(RFP);

# display set
$cmd = 'i2cset -y 1 0x3c 0x00 0xa0 0xc0 i';
system($cmd);

# horizontal mode
#    column = 0 ... 127
#    page = 0 ... 7
$cmd = 'i2cset -y 1 0x3c 0x00 0x20 0x00 0x21 0x00 0x7f 0x22 0x00 0x07 i';
system($cmd);

$i = 0;
for($h=0; $h<$height; $h+=8){
  for($w=0; $w<$width; $w++){
    $d = unpack("C", pack("B8", $pbm[$h+7][$w] .
                                $pbm[$h+6][$w] .
                                $pbm[$h+5][$w] .
                                $pbm[$h+4][$w] .
                                $pbm[$h+3][$w] .
                                $pbm[$h+2][$w] .
                                $pbm[$h+1][$w] .
                                $pbm[$h+0][$w]));
    if($i==0){
      $cmd = "i2cset -y 1 0x3c 0x40 ";
    }
    $cmd .= sprintf("0x%02x ", $d);
    $i++;
    if($i==16){
      $i = 0;
      $cmd .= "i";
      system($cmd);
    }
  }
}

# display enable
$cmd = 'i2cset -y 1 0x3c 0x00 0x8d 0x14 0xaf i';
system($cmd);


引数にpbmファイルを指定して実行させます。

$ ./disp128x64.pl miku.pbm

写真ではちょっと見難いですが綺麗に表示できました。

[参考記事]