M5Stack:レトロパソコン風CG データダイエット

ガッツでC.G.!サポートツール」で LINE&PAINT CG を描くと、1データあたり 100KB~200KBぐらいになります。8ビットPCの頃に比べると、超贅沢なデータ量ですね。

M5Atom でCG描画アプリを実行するときは、このデータをフラッシュメモリ(SPIFFS)に格納するわけですが、フラッシュメモリのデータ格納容量が2MB程度しか確保できなくて、そうすると 100KB だと 20枚程度が限界になってしまうのですよね。

外付けでSDカードを接続するのもアリですが、ミニチュアモニタで使っている 240×240 1.3インチディスプレイはCSピンを持ってないため、SDカードとLCDでSPI接続共有するのが難しく、M5Atom だとピンが足りないわけです。
そんなわけで、少しでもファイルサイズを小さくしたい。


「ガッツでC.G.!サポートツール」は線を引くときにかなり贅沢にポイント座標を取得してます。
こういう風になってるところも多いです。

このとき、(X1,Y1)-(X2,Y2)の角度と(X1,Y1)-(X3,Y3)の角度が同じであれば(X2,Y2)は省略することが可能ですね。

生成済みの描画データに対して、この処理を行うツールを Python で書いてみました。

import sys
import os

if len(sys.argv) > 1:
    fileName = sys.argv[1]
else:
    fileName = "MagicalMirai2018.dat"
    #print("ファイル名を指定してください")
    #sys.exit()

cgData = open(fileName, encoding="utf-8")

file, ext = os.path.splitext(fileName)

dietData = open(file + "_diet.dat", mode='w', encoding="utf-8")

line = cgData.readline() #1行目はタイトル
dietData.write(line)


#直線になっている場合、途中の点を省略する。
lineMode = False
while line:
    line = cgData.readline()
    print("line:" + line)
    lineData = line.rstrip().split(',')
    #-10から始まっていたら、LINEモード。LINEは1行1LINE
    if len(lineData) == 0:
        continue
    if line.startswith('-10'):
        lineMode = True
        dietData.write(lineData.pop(0))
        dietData.write(',')
    elif line.startswith('-1'):
        lineMode = False
        dietData.write(line)
    elif lineMode == False:
        dietData.write(line)
    if lineMode == True:
        dietData.write(lineData.pop(0)) #color
        dietData.write(',')
        index = 0
        while(1):
            if index + 5 >= len(lineData):
                dietData.write(",".join(lineData))
                dietData.write("\n")
                break
            #(x1,y1)-(x2,y2)の傾きと、(x1,y1)-(x3,y3)の傾きが同じであれば(x2,y2)を削除できる。
            x1 = int(lineData[index + 0])
            y1 = int(lineData[index + 1])
            x2 = int(lineData[index + 2])
            y2 = int(lineData[index + 3])
            x3 = int(lineData[index + 4])
            y3 = int(lineData[index + 5])
            if(y1 - y2 == 0) and (y1 - y3 == 0):
                #両方傾きゼロだけ特別扱い
                del lineData[index+2]
                del lineData[index+2] #詰まっているので同じINDEX
            elif(y1 - y2 == 0) or (y1 - y3 == 0):
                #分母ゼロなので割れない
                index = index + 2
            elif (x1-x2) / (y1 - y2) == (x1-x3) / (y1 -y3):
                del lineData[index+2]
                del lineData[index+2] #詰まっているので同じINDEX
            else:
                index = index + 2
dietData.close()
cgData.close()

元ファイル:MagicalMirai2018.dat : 194,551 byte
実行後ファイル:MagicalMirai2018.diet.dat :126,695 byte

小さくなった!(その分、描画の時も少々クイックになります)


最初からこの処理を「ガッツでC.G.!サポートツール」の線引き処理に組み込んどけばよいのですよね…。

var point = [Math.round(mouse.x),Math.round(mouse.y)];
//前回と傾きが同じだった場合、前回のポイントは削除する。
if(curDrawData.length >=2){
    point1 = curDrawData[curDrawData.length-2]; 
    point2 = curDrawData[curDrawData.length-1]; 
    x1 = point1[0];
    y1 = point1[1];
    x2 = point2[0];
    y2 = point1[1];
    x3 = point[0];
    y3 = point[1];
    if((y1 - y2 == 0) && (y1 - y3 == 0)){
        //両方傾きゼロだけ特別扱い
        curDrawData.pop();
    }else if((y1 - y2 == 0) || (y1 - y3 == 0)){
        //分母ゼロなので割れない
    }else if((x1-x2) / (y1 - y2) == (x1 - x3) / (y1 - y3)){
        curDrawData.pop();
    }
}
curDrawData.push(point);

…ということで、こちらも先ほど組み込み終わりました!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です