Skip to content

Conversation

@bclehmann
Copy link
Contributor

I used the following python script (requires python 3 and the cairosvg package):

import os
from cairosvg import svg2png
from pathlib import Path

SOURCE_DIR = "./lila/public/piece"
DEST_DIR = "./flutter-chessground/lib/piece_sets"
SCALING_FACTORS = [
    (1, "."),
    (2, "./2.0x"),
    (3, "./3.0x"),
    (4, "./4.0x")
]

for dname in os.listdir(SOURCE_DIR):
    dpath = os.path.join(SOURCE_DIR, dname)

    if not os.path.isdir(dpath):
        continue

    for (factor, folder) in SCALING_FACTORS:
        for fname in os.listdir(dpath):
            fpath = os.path.join(dpath, fname)

            if not os.path.isfile(fpath):
                continue

            out_folder = os.path.join(DEST_DIR, dname, folder)
            print(out_folder)
            if not os.path.exists(out_folder):
                os.makedirs(out_folder)

            fname_without_extension = Path(fname).stem
            png = os.path.join(out_folder, fname_without_extension + ".png")
            print(f"Converting {fpath} to {png}")
            size = 128 * factor
            svg2png(url=fpath, write_to=png, output_width=size, output_height=size)

Please note that this script chokes on the disguised piece set, I opened them and the're just text files with the text b.svg or w.svg. This makes me think that these were supposed to be symlinks that git didn't clone correctly. Since it was one piece set I decided to clean it up by hand.

@bclehmann
Copy link
Contributor Author

Similarly, to generate the dart code I used this script:

PIECE_SETS = [
    "alpha", "anarcandy", "california", "cardinal", "cburnett", "celtic", "chess7", "chessnut", "companion", "disguised", "dubrovny",
    "fantasy", "fresca", "gioco", "governor", "horsey", "icpieces", "kosal", "leipzig", "letter", "libra", "maestro", "merida", "mono",
    "pirouetti", "pixel", "reillycraig", "riohacha", "shapes", "spatial", "staunty", "tatiana"
]

for name in PIECE_SETS:
    print("""
    const PieceSet {name}PieceSet = {{
        'blackrook':
        AssetImage('lib/piece_sets/{name}/bR.png', package: 'chessground'),
        'blackpawn':
        AssetImage('lib/piece_sets/{name}/bP.png', package: 'chessground'),
        'blackknight':
        AssetImage('lib/piece_sets/{name}/bN.png', package: 'chessground'),
        'blackbishop':
        AssetImage('lib/piece_sets/{name}/bB.png', package: 'chessground'),
        'blackqueen':
        AssetImage('lib/piece_sets/{name}/bQ.png', package: 'chessground'),    
        'blackking':
        AssetImage('lib/piece_sets/{name}/bK.png', package: 'chessground'),      
        'whiterook':
        AssetImage('lib/piece_sets/{name}/wR.png', package: 'chessground'),
        'whitepawn':
        AssetImage('lib/piece_sets/{name}/wP.png', package: 'chessground'),
        'whiteknight':
        AssetImage('lib/piece_sets/{name}/wN.png', package: 'chessground'),
        'whitebishop':
        AssetImage('lib/piece_sets/{name}/wB.png', package: 'chessground'),
        'whitequeen':
        AssetImage('lib/piece_sets/{name}/wQ.png', package: 'chessground'),    
        'whiteking':
        AssetImage('lib/piece_sets/{name}/wK.png', package: 'chessground'),        
    }};
    """.format(name=name))

Unfortunately it seems that specifying an asset directory in pubspec.yaml only brings in the direct descendants, which is inconvenient here. In any case, I got it working:
image

@bclehmann bclehmann marked this pull request as ready for review February 3, 2023 00:54
@bclehmann
Copy link
Contributor Author

I know that SVGs are strangely difficult in flutter, but it's worth noting that using pngs here uses almost 20 MiB, and in lila it takes about 2, not to mention the added difficulty in importing. I'm sure it can be cut down as I don't believe we're using the higher resolution versions, but it might be worth looking into alternatives.

@schlawg
Copy link
Contributor

schlawg commented Feb 3, 2023

You could probably chop 10-15% off storage costs for these by using run length encoding rather than LZW as they're 1 bit images with 1 bit alphas. If you care to check if it's worth it - just cd to piecesets, and run mogrify -compress RLE `find . | grep '\.png$'` (mogrify is installed by imagemagick)

What's the difficulty with flutter and SVGs? Are you guys concerned about rasterization cost? The flutter_svg package worked well when I tried it.

@veloce
Copy link
Collaborator

veloce commented Feb 3, 2023

I'd rather keep the PNG than to rely on flutter_svg. And we have the perf gain because no rasterization.

Not sure I want to have all the pieces loaded into the app by default thought because it means 20MB more into the app bundle, (without counting the pngs of the boards). In the previous app one would download them on demand. A bit more work but definitely doable.

On the other hand, if we download them on demand we'd loose the const benefit. Is that benefit really important for perf? not so sure, but I don't think so. Still, in the application the chessboard is the widget where performance matters the most.

For the record I used the svgexport node package to convert merida: https://www.npmjs.com/package/svgexport

With simple shell commands like:

for file in $(ls .)\nsvgexport $file ~/tmp/merida/4.0x/"${file%.*}".png 512:512

Looking at your script it seems you converted merida as well, so there's no diff between the python and node tool apparently.

@veloce
Copy link
Collaborator

veloce commented Feb 3, 2023

I guess we could add 20MB in the app size, but it would be nice to also know the size of all the board themes. I'll make an issue for that.

@schlawg
Copy link
Contributor

schlawg commented Feb 3, 2023

Most modern games, even indies, contain 100+ MB of graphical assets. It's good to keep an eye on but 20 is fine!

@veloce veloce merged commit aa20128 into lichess-org:main Feb 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants