CNCMaps.Engine.Map.Map.GeneratePreviewPack C# (CSharp) Метод

GeneratePreviewPack() публичный Метод

public GeneratePreviewPack ( PreviewMarkersType previewMarkers, SizeMode sizeMode, System.IniFile map, bool fixDimensions ) : void
previewMarkers PreviewMarkersType
sizeMode SizeMode
map System.IniFile
fixDimensions bool
Результат void
        public void GeneratePreviewPack(PreviewMarkersType previewMarkers, SizeMode sizeMode, IniFile map, bool fixDimensions)
        {
            Logger.Info("Generating PreviewPack data");

            // we will have to re-lock the BitmapData
            _drawingSurface.Lock(_drawingSurface.Bitmap.PixelFormat);
            if (MarkOreFields == false) {
                Logger.Trace("Marking ore and gems areas");
                MarkOreAndGems();
                Logger.Debug("Redrawing ore and gems areas");
                RedrawOreAndGems();
            }
            // undo tiled, if needed
            if (StartPosMarking == StartPositionMarking.Tiled)
                UndrawTiledStartPositions();
            _drawingSurface.Unlock();

            switch (previewMarkers) {
            case PreviewMarkersType.None:
                break;
            case PreviewMarkersType.Squared:
                DrawSquaredStartPositions();
                break;
            case PreviewMarkersType.Bittah:
            case PreviewMarkersType.Aro:
                // to be injected later
                break;
            }

            // Number magic explained: http://modenc.renegadeprojects.com/Maps/PreviewPack
            int pw, ph;
            switch (Engine) {
            case EngineType.TiberianSun:
                pw = (int)Math.Ceiling((fixDimensions ? 1.975 : 2.000) * FullSize.Width);
                ph = (int)Math.Ceiling((fixDimensions ? 0.995 : 1.000) * FullSize.Height);
                break;
            case EngineType.Firestorm:
                pw = (int)Math.Ceiling((fixDimensions ? 1.975 : 2.000) * FullSize.Width);
                ph = (int)Math.Ceiling((fixDimensions ? 0.995 : 1.000) * FullSize.Height);
                break;
            case EngineType.RedAlert2:
                pw = (int)Math.Ceiling((fixDimensions ? 1.975 : 2.000) * FullSize.Width);
                ph = (int)Math.Ceiling((fixDimensions ? 0.995 : 1.000) * FullSize.Height);
                break;
            case EngineType.YurisRevenge:
                pw = (int)Math.Ceiling((fixDimensions ? 1.975 : 2.000) * LocalSize.Width);
                ph = (int)Math.Ceiling((fixDimensions ? 1.000 : 1.000) * LocalSize.Height);
                break;
            default:
                throw new ArgumentOutOfRangeException();
            }

            using (var preview = new Bitmap(pw, ph, PixelFormat.Format24bppRgb)) {

                using (Graphics gfx = Graphics.FromImage(preview)) {
                    // use high-quality scaling
                    gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    gfx.SmoothingMode = SmoothingMode.HighQuality;
                    gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    gfx.CompositingQuality = CompositingQuality.HighQuality;

                    var srcRect = GetSizePixels(sizeMode);
                    var dstRect = new Rectangle(0, 0, preview.Width, preview.Height);
                    gfx.DrawImage(_drawingSurface.Bitmap, dstRect, srcRect, GraphicsUnit.Pixel);

                    switch (previewMarkers) {
                    case PreviewMarkersType.None:
                    case PreviewMarkersType.Squared:
                        break;
                    case PreviewMarkersType.Bittah:
                        DrawStartMarkersBittah(gfx, srcRect, dstRect);
                        break;
                    case PreviewMarkersType.Aro:
                        DrawStartMarkersAro(gfx, srcRect, dstRect);
                        break;
                    }
                }

                Logger.Info("Injecting thumbnail into map");
                ThumbInjector.InjectThumb(preview, map);

                // debug thing to dump original previewpack dimensions
                // preview.Save("C:\\thumbs\\" + Program.Settings.OutputFile + ".png");
                // var originalPreview = ThumbInjector.ExtractThumb(this);
                /*var prev = GetSection("Preview");
                if (prev != null) {
                    var name = DetermineMapName(this.EngineType);
                    var size = GetSection("Preview").ReadString("Size").Split(',');
                    var previewSize = new Rectangle(int.Parse(size[0]), int.Parse(size[1]), int.Parse(size[2]), int.Parse(size[3]));

                    File.AppendAllText("C:\\thumbs\\map_preview_dimensions.txt",
                                        string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\n", name,
                                        previewSize.Width, previewSize.Height, LocalSize.Width, LocalSize.Height, FullSize.Width, FullSize.Height));
                }*/
            }
        }

Usage Example

Пример #1
0
        public EngineResult Execute()
        {
            try {
                _logger.Info("Initializing virtual filesystem");

                var mapStream = File.Open(Settings.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                VirtualFile vmapFile;
                var mixMap = new MixFile(mapStream, Settings.InputFile, 0, mapStream.Length, false, false);
                if (mixMap.IsValid()) { // input max is a mix
                    var mapArchive = new MixFile(mapStream, Path.GetFileName(Settings.InputFile), true);
                    // grab the largest file in the archive
                    var mixEntry = mapArchive.Index.OrderByDescending(me => me.Value.Length).First();
                    vmapFile = mapArchive.OpenFile(mixEntry.Key);
                }
                else {
                    vmapFile = new VirtualFile(mapStream, Path.GetFileName(Settings.InputFile), true);
                }
                var mapFile = new MapFile(vmapFile, Path.GetFileName(Settings.InputFile));

                if (!string.IsNullOrEmpty(Settings.ModConfig)) {
                    if (File.Exists(Settings.ModConfig)) {
                        ModConfig cfg;
                        try {
                            using (FileStream f = File.OpenRead(Settings.ModConfig))
                                cfg = ModConfig.Deserialize(f);
                            ModConfig.ActiveConfig = cfg;
                            if (Settings.Engine != EngineType.AutoDetect) {
                                if (Settings.Engine != cfg.Engine)
                                    _logger.Warn("Provided engine override does not match mod config.");
                            }
                            else
                                Settings.Engine = ModConfig.ActiveConfig.Engine;
                        }
                        catch (IOException) {
                            _logger.Fatal("IOException while loading mod config");
                        }
                        catch (XmlException) {
                            _logger.Fatal("XmlException while loading mod config");
                        }
                        catch (SerializationException) {
                            _logger.Fatal("Serialization exception while loading mod config");
                        }
                    }
                    else {
                        _logger.Fatal("Invalid mod config file specified");
                    }
                }

                if (Settings.Engine == EngineType.AutoDetect) {
                    Settings.Engine = EngineDetector.DetectEngineType(mapFile);
                    _logger.Info("Engine autodetect result: {0}", Settings.Engine);
                }

                // ---------------------------------------------------------------
                // Code to organize moving of maps in a directory for themselves
                /*
                string mapName = DetermineMapName(mapFile, Settings.Engine);
                string ndir = Path.Combine(Path.GetDirectoryName(Settings.InputFile), mapName);
                if (!Directory.Exists(ndir)) Directory.CreateDirectory(ndir);
                mapFile.Close();
                mapFile.Dispose();
                File.Move(Settings.InputFile, Path.Combine(ndir, Path.GetFileName(mapFile.FileName)));
                return 0;*/
                // ---------------------------------------------------------------

                // enginetype is now definitive, load mod config
                if (ModConfig.ActiveConfig == null)
                    ModConfig.LoadDefaultConfig(Settings.Engine);

                // first add the dirs, then load the extra mixes, then scan the dirs
                foreach (string modDir in ModConfig.ActiveConfig.Directories)
                    VFS.Add(modDir);

                // add mixdir to VFS (if it's not included in the mod config)
                if (!ModConfig.ActiveConfig.Directories.Any()) {
                    string mixDir = VFS.DetermineMixDir(Settings.MixFilesDirectory, Settings.Engine);
                    VFS.Add(mixDir);
                }
                foreach (string mixFile in ModConfig.ActiveConfig.ExtraMixes)
                    VFS.Add(mixFile);

                VFS.Instance.LoadMixes(Settings.Engine);

                var map = new Map.Map {
                    IgnoreLighting = Settings.IgnoreLighting,
                    StartPosMarking = Settings.StartPositionMarking,
                    MarkOreFields = Settings.MarkOreFields
                };

                if (!map.Initialize(mapFile, Settings.Engine, ModConfig.ActiveConfig.CustomRulesIniFiles, ModConfig.ActiveConfig.CustomArtIniFiles)) {
                    _logger.Error("Could not successfully load this map. Try specifying the engine type manually.");
                    return EngineResult.LoadRulesFailed;
                }

                if (!map.LoadTheater()) {
                    _logger.Error("Could not successfully load all required components for this map. Aborting.");
                    return EngineResult.LoadTheaterFailed;
                }

                if (Settings.StartPositionMarking == StartPositionMarking.Tiled)
                    map.MarkTiledStartPositions();

                if (Settings.MarkOreFields)
                    map.MarkOreAndGems();

                if (Settings.FixupTiles) map.FixupTileLayer();
                map.Draw();

                if (Settings.StartPositionMarking == StartPositionMarking.Squared)
                    map.DrawSquaredStartPositions();

            #if DEBUG
                // ====================================================================================
                using (var form = new DebugDrawingSurfaceWindow(map.GetDrawingSurface(), map.GetTiles(), map.GetTheater(), map)) {
                    form.RequestTileEvaluate += map.DebugDrawTile; form.ShowDialog();
                }
                // ====================================================================================
            #endif

                if (Settings.OutputFile == "")
                    Settings.OutputFile = DetermineMapName(mapFile, Settings.Engine);

                if (Settings.OutputDir == "")
                    Settings.OutputDir = Path.GetDirectoryName(Settings.InputFile);

                // free up as much memory as possible before saving the large images
                Rectangle saveRect = map.GetSizePixels(Settings.SizeMode);
                DrawingSurface ds = map.GetDrawingSurface();
                saveRect.Intersect(new Rectangle(0, 0, ds.Width, ds.Height));
                // if we don't need this data anymore, we can try to save some memory
                if (!Settings.GeneratePreviewPack) {
                    ds.FreeNonBitmap();
                    map.FreeUseless();
                    GC.Collect();
                }

                if (Settings.SaveJPEG)
                    ds.SaveJPEG(Path.Combine(Settings.OutputDir, Settings.OutputFile + ".jpg"), Settings.JPEGCompression, saveRect);

                if (Settings.SavePNG)
                    ds.SavePNG(Path.Combine(Settings.OutputDir, Settings.OutputFile + ".png"), Settings.PNGQuality, saveRect);

                Regex reThumb = new Regex(@"(\+|)?\((\d+),(\d+)\)");
                var match = reThumb.Match(Settings.ThumbnailConfig);
                if (match.Success) {
                    Size dimensions = new Size(
                        int.Parse(match.Groups[2].Captures[0].Value),
                        int.Parse(match.Groups[3].Captures[0].Value));
                    var cutRect = map.GetSizePixels(Settings.SizeMode);

                    if (match.Groups[1].Captures[0].Value == "+") {
                        // + means maintain aspect ratio
                        double aspectRatio = cutRect.Width / (double)cutRect.Height;
                        if (dimensions.Width / (double)dimensions.Height > aspectRatio) {
                            dimensions.Height = (int)(dimensions.Width / aspectRatio);
                        }
                        else {
                            dimensions.Width = (int)(dimensions.Height / aspectRatio);
                        }
                    }
                    _logger.Info("Saving thumbnail with dimensions {0}x{1}", dimensions.Width, dimensions.Height);
                    ds.SaveThumb(dimensions, cutRect, Path.Combine(Settings.OutputDir, "thumb_" + Settings.OutputFile + ".jpg"));
                }

                if (Settings.GeneratePreviewPack || Settings.FixupTiles) {
                    if (mapFile.BaseStream is MixFile)
                        _logger.Error("Cannot fix tile layer or inject thumbnail into an archive (.mmx/.yro/.mix)!");
                    else {
                        if (Settings.GeneratePreviewPack)
                            map.GeneratePreviewPack(Settings.PreviewMarkers, Settings.SizeMode, mapFile, Settings.FixPreviewDimensions);

                        _logger.Info("Saving map to " + Settings.InputFile);
                        mapFile.Save(Settings.InputFile);
                    }
                }
            }
            catch (Exception exc) {
                _logger.Error(string.Format("An unknown fatal exception occured: {0}", exc), exc);
            #if DEBUG
                throw;
            #endif
                return EngineResult.Exception;
            }
            return EngineResult.RenderedOk;
        }