public static void SaveTo(Stream outputStream, PixelArtDocument document)
        {
            // パレットの生成
            var itemPalette = new List <IMCItem>();

            foreach (var item in document.Pixels)
            {
                if (itemPalette.Contains(item) == false)
                {
                    itemPalette.Add(item);
                }
            }

            // ピクセル データのインデックス変換
            var pixelValues = document.Pixels.Select(item => (short)itemPalette.IndexOf(item)).ToArray();

            // 書き出し
            using (var binaryWriter = new BinaryWriter(outputStream))
            {
                binaryWriter.Write(_fileMn);
                using (var propWriter = new PropWriter(outputStream))
                {
                    var metaSec = new PropSection("mcpixart-file-meta");
                    metaSec.Items.Add(new PropItem("magic-number", PropType.String, "  MCPIXART  "));
                    metaSec.Items.Add(new PropItem("file-description", PropType.String, " This is MC Pixel Art Navi Document File. Please visit our web site: https://www.a32kita.net/ "));
                    metaSec.Items.Add(new PropItem("file-version", PropType.Int64, 1L));
                    metaSec.Items.Add(new PropItem("created-at", PropType.DateTime, DateTime.Now));

                    var docSec = new PropSection("mcpixart-file-doc");
                    docSec.Items.Add(new PropItem("document-title", PropType.String, document.DocumentTitle));
                    docSec.Items.Add(new PropItem("document-author", PropType.String, document.DocumentAuthor));
                    docSec.Items.Add(new PropItem("document-description", PropType.String, document.DocumentDescription));
                    docSec.Items.Add(new PropItem("art-size", PropType.Int16, (short)document.Size));
                    docSec.Items.Add(new PropItem("art-palette", PropType.StringArray, itemPalette.Select(item => item.ItemId).ToArray()));
                    docSec.Items.Add(new PropItem("art-pixels", PropType.Int16Array, pixelValues));

                    propWriter.Write(new Props(new PropSection[] { metaSec, docSec }));
                }
            }
        }
Exemple #2
0
        // 公開メソッド

        /// <summary>
        ///
        /// </summary>
        /// <param name="document">マップアート データ</param>
        /// <param name="stream">このオプションは使用されません。</param>
        /// <param name="baseDirectory">出力先ディレクトリ</param>
        /// <returns></returns>
        public override async Task <ExportResult> ExportAsync(PixelArtDocument document, Stream stream, string baseDirectory)
        {
            if (baseDirectory == null)
            {
                throw new ArgumentNullException(nameof(baseDirectory));
            }

            if (File.Exists(baseDirectory) || Directory.Exists(baseDirectory))
            {
                throw new ArgumentException(nameof(baseDirectory));
            }

            var baseName = Path.GetFileName(baseDirectory);
            var utf8nEnc = new UTF8Encoding(false);

            Directory.CreateDirectory(baseDirectory);

            using (var swPackMeta = new StreamWriter(Path.Combine(baseDirectory, "pack.mcmeta"), false, utf8nEnc))
            {
                swPackMeta.WriteLine("{");
                swPackMeta.WriteLine("  \"pack\": {");
                swPackMeta.WriteLine("    \"pack_format\": 1,");
                swPackMeta.WriteLine("    \"description\": \"datapack\"");
                swPackMeta.WriteLine("  }");
                swPackMeta.WriteLine("}");
            }

            var dataDirPath = Path.Combine(baseDirectory, "data");

            Directory.CreateDirectory(dataDirPath);

            var packDirPath = Path.Combine(dataDirPath, baseName);

            Directory.CreateDirectory(packDirPath);

            var functionsDir = Path.Combine(packDirPath, "functions");

            Directory.CreateDirectory(functionsDir);

            var mcFunctionFilePath = Path.Combine(functionsDir, baseName + ".mcfunction");

            var     sw          = new StreamWriter(mcFunctionFilePath, false, utf8nEnc);
            IMCItem currentItem = document.Pixels[0];
            var     currentItemStartPositionX = 0;
            var     currentItemStartPositionZ = 0;

            for (var row = 0; row < document.Size.GetHeight(); row++)
            {
                for (var col = 0; col < document.Size.GetWidth(); col++)
                {
                    var nextItemNum = (row * document.Size.GetWidth()) + col;
                    var nextItem    = document.Pixels[nextItemNum];
                    if (currentItem != nextItem)
                    {
                        if (col == 0)
                        {
                            // 左端の場合 → 先に変更
                            currentItem = nextItem;
                        }

                        // コマンドの出力
                        await this._writeFillCommand(sw, currentItemStartPositionX, currentItemStartPositionZ, col, row, currentItem.ItemId);

                        // currentItem の変更
                        currentItem = nextItem;
                        currentItemStartPositionX = col + 1;
                    }
                }

                // コマンドの出力
                await this._writeFillCommand(sw, currentItemStartPositionX, currentItemStartPositionZ, document.Size.GetWidth(), row, currentItem.ItemId);

                currentItemStartPositionX = 0;
                currentItemStartPositionZ = row + 1;
            }

            await sw.FlushAsync();

            return(new ExportResult());
        }
Exemple #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="document">マップアート データ</param>
        /// <param name="stream">書き込み先ファイルのストリーム</param>
        /// <param name="baseDirectory">このオプションは使用されません</param>
        /// <returns></returns>
        public override async Task <ExportResult> ExportAsync(PixelArtDocument document, Stream stream, string baseDirectory)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);

            var workbookPart = spreadsheetDocument.AddWorkbookPart();

            workbookPart.Workbook = new Workbook();

            var worksheetPart = workbookPart.AddNewPart <WorksheetPart>();

            worksheetPart.Worksheet = new Worksheet(
                // SheetData よりも先に Columns が必要
                new Columns(new Column()
            {
                // 列の幅など
                Min         = 1u,
                Max         = (uint)document.Size.GetWidth(),
                Width       = 3,
                CustomWidth = true,
            }),
                new SheetData());

            var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild <Sheets>(new Sheets());

            var sheet = new Sheet()
            {
                Id      = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
                SheetId = 1,
                Name    = "MCPixelArtNavi"
            };

            sheets.Append(sheet);

            var sheetData  = worksheetPart.Worksheet.GetFirstChild <SheetData>();
            var stylesPart = workbookPart.AddNewPart <WorkbookStylesPart>();

            // スタイル生成 :: アイテム塗りつぶしの生成
            var enabledItems = MCItemUtils.EnabledItems.ToList();
            var fillList     = new List <Fill>();

            // Fill[0]: デフォルト fill の追加 (頭に追加してデフォルト化)
            fillList.Add(new Fill()
            {
                // 固定値
                PatternFill = new PatternFill()
                {
                    PatternType = PatternValues.None
                }
            });

            // Fill[1]: 予約枠を潰す
            fillList.Add(new Fill()
            {
                // 固定値
                PatternFill = new PatternFill()
                {
                    PatternType = PatternValues.Gray125
                }
            });

            // Fill[2 ~]: アイテムの色情報の Fill
            fillList.AddRange(enabledItems.Select(this._createFillFromMCItem));

            // デフォルト fill を含む、すべての fill に対応する cellFormat の生成
            var cellFormatList = fillList.Select((e, idx) => this._createCellFormatFromFill(idx)).ToList();

            // デフォルト フォント (特に中身にこだわりはない)
            var font = new Font(new Color()
            {
                Theme = UInt32Value.FromUInt32(1U)
            })
            {
                FontName = new FontName()
                {
                    Val = StringValue.FromString("Arial")
                },
                FontSize = new FontSize()
                {
                    Val = DoubleValue.FromDouble(11d)
                },
                FontFamilyNumbering = new FontFamilyNumbering()
                {
                    Val = 2
                },
                FontCharSet = new FontCharSet()
                {
                    Val = 128
                },
                FontScheme = new FontScheme()
                {
                    Val = FontSchemeValues.Minor
                },
            };

            // デフォルト セル スタイル
            var cellStyle = new CellStyle()
            {
                Name      = StringValue.FromString("Normal"),
                FormatId  = 0,
                BuiltinId = 0,
            };

            stylesPart.Stylesheet = new Stylesheet(
                new Fonts(font),
                new Fills(fillList),
                new Borders(new Border()),
                new CellFormats(cellFormatList),
                new CellStyles(cellStyle),
                new DifferentialFormats(),
                new TableStyles()
            {
                DefaultTableStyle = StringValue.FromString("TableStyleMedium9"),
                DefaultPivotStyle = StringValue.FromString("PivotStyleLight16"),
            });


            // 行作成
            var rows = new Row[document.Size.GetHeight()];
            var p    = 0;

            for (var i = 0; i < rows.Length; i++)
            {
                // 列作成
                rows[i] = new Row()
                {
                    RowIndex = new UInt32Value((uint)(i + 1))
                };
                for (var j = 0; j < document.Size.GetWidth(); j++, p++)
                {
                    var cell = new Cell()
                    {
                        CellReference = this._toCellReference(j, i),
                        CellValue     = new CellValue(""),
                        DataType      = CellValues.String,
                        StyleIndex    = (uint)(enabledItems.IndexOf(document.Pixels[p]) + 2),
                    };
                    rows[i].InsertAt(cell, j);
                }

                sheetData.Append(rows[i]);
            }

            workbookPart.Workbook.Save();
            spreadsheetDocument.Close();

            return(new ExportResult());
        }
 public abstract Task <ExportResult> ExportAsync(PixelArtDocument document, Stream stream, string baseDirectory);