예제 #1
0
        /// <summary>
        /// parses image and write arrays to output file
        /// </summary>
        /// <param name="options">parsed command line args</param>
        /// <returns>error code</returns>
        static int ParseFontImage(ParseOptions options)
        {
            try
            {
                var bitmap   = new Bitmap(Image.FromFile(options.InputFileName));
                var settings = PixelSettings.FromFile(options.PixelSettingsPath);
                var mapper   = new PixelMapper(bitmap, settings);
                var map      = mapper.MapPixels();
                OutputFileFormatter.WriteOutput(map, options.OutputFileName, options.SingleArray);
            }
            catch (Exception e)
            {
                if (e is FileNotFoundException)
                {
                    ConsoleLogger.WriteMessage($"File not found or invalid file name \"{e.Message}\"", MessageType.Error);
                    return((int)ErrorCode.FileNotFound);
                }

                ConsoleLogger.WriteMessage(e.Message + "\n" + e.InnerException?.Message, MessageType.Error);

                if (e is ArgumentException)
                {
                    return((int)ErrorCode.FileParsingError);
                }

                return((int)ErrorCode.UknownError);
            }
            return((int)ErrorCode.NoError);
        }
예제 #2
0
        /// <summary>
        /// Fills bitmap with solid color and draws a grid on it
        /// </summary>
        /// <param name="patternWidthCount">width of grid in symbols (cells)</param>
        /// <param name="patternHeightCount">height of grid in symbols (cells)</param>
        /// <returns>production ready bitmap</returns>
        public Bitmap GeneratePattern(int patternWidthCount, int patternHeightCount,
                                      EnumerationStyle enumerationStyle, byte[] sampleData = null)
        {
            if (enumerationStyle != EnumerationStyle.None)
            {
                patternHeightCount++;
                patternWidthCount++;
            }

            var pattentWidth = patternWidthCount * _settings.SymbolWidth +
                               (patternWidthCount - 1) * _settings.DelimeterWidth;
            var patternHeight = patternHeightCount * _settings.SymbolHeight +
                                (patternHeightCount - 1) * _settings.DelimeterHeight;
            var pattern = new Bitmap(pattentWidth, patternHeight);

            ConsoleLogger.WriteMessage($"Generating pattern\nBitmap size {pattentWidth} x {patternHeight} px", MessageType.Info);

            FillBackground(pattern);
            DrawVerticalLines(pattern);
            DrawHorizontalLines(pattern);
            Enumerate(pattern, enumerationStyle);
            if (sampleData != null)
            {
                FillSampleData(pattern, sampleData, enumerationStyle);
            }
            return(pattern);
        }
예제 #3
0
        static int Main(string[] args)
        {
            var options = new CommandLineOptions();

            if (!Parser.Default.ParseArguments(args, options,
                                               (verb, suboptions) =>
            {
                _invokedVerb = verb;
                _suboptions = (CommonOptions)suboptions;
            }))
            {
                Environment.Exit((int)ErrorCode.ArgumentsMismatch);
            }


            int errorCode = (int)ErrorCode.NoError;

            if (_invokedVerb == "generate")
            {
                errorCode = GeneratePattern((GenerateOptions)_suboptions);
            }
            if (_invokedVerb == "parse")
            {
                errorCode = ParseFontImage((ParseOptions)_suboptions);
            }

            if (errorCode == (int)ErrorCode.NoError)
            {
                ConsoleLogger.WriteMessage($"SUCCESS! \nFile written: \"{_suboptions.OutputFileName}\"", MessageType.Info);
            }
            return(errorCode);
        }
예제 #4
0
        static int Main(string[] args)
        {
            // Parse command-line arguments
            try
            {
                Parser.Default.ParseArguments <GenerateOptions, ParseOptions>(args)
                .MapResult(
                    (GenerateOptions options) => GeneratePattern(options),
                    (ParseOptions options) => ParseFontImage(options),
                    // just exit, this usually means that no arguments were given
                    (errs) =>
                {
                    System.Environment.Exit(1);
                    return(null);
                });
            }
            catch (Exception e)
            {
                NotifyError(e);
                return(1);
            }

            ConsoleLogger.WriteMessage($"SUCCESS! \nFile written: \"{_outputFileName}\"", MessageType.Info);

            return(0);
        }
예제 #5
0
        // Notifies user about error details
        private static void NotifyError(ErrorCode errorCode)
        {
            //  todo:  add more details
            switch (errorCode)
            {
            case ErrorCode.UknownError:
                ConsoleLogger.WriteMessage("There was error, but we have no idea why.", MessageType.Error);
                break;

            case ErrorCode.ArgumentsMismatch:
                ConsoleLogger.WriteMessage("Error parsing arguments. Check command line.", MessageType.Error);
                break;

            case ErrorCode.FileNotFound:
                ConsoleLogger.WriteMessage("File was not found", MessageType.Error);
                break;

            case ErrorCode.FileParsingError:
                ConsoleLogger.WriteMessage("Error parsing file", MessageType.Error);
                break;

            case ErrorCode.ArgumentsNotParsed:
                //do nothings as this usually means that no arguments were passed to command line
                break;
            }
        }
예제 #6
0
        /// <summary>
        /// Fills bitmap with solid color and draws a grid on it
        /// </summary>
        /// <param name="patternWidthCount">width of grid in symbols (cells)</param>
        /// <param name="patternHeightCount">height of grid in symbols (cells)</param>
        /// <returns>production ready bitmap</returns>
        public Bitmap GeneratePattern(int patternWidthCount, int patternHeightCount)
        {
            var pattentWidth = patternWidthCount * _settings.SymbolWidth +
                               (patternWidthCount - 1) * _settings.DelimeterWidth;
            var patternHeight = patternHeightCount * _settings.SymbolHeight +
                                (patternHeightCount - 1) * _settings.DelimeterHeight;
            var pattern = new Bitmap(pattentWidth, patternHeight);

            ConsoleLogger.WriteMessage($"Generating pattern\nBitmap size {pattentWidth} x {patternHeight} px", MessageType.Info);

            FillBackground(pattern);
            DrawVerticalLines(pattern);
            DrawHorizontalLines(pattern);

            return(pattern);
        }
예제 #7
0
        // Notifies user about error details
        private static void NotifyError(Exception e)
        {
            switch (e)
            {
            case FileNotFoundException _:
                ConsoleLogger.WriteMessage($"File not found: {e.Message}", MessageType.Error);
                return;

            case ArgumentException _:
                ConsoleLogger.WriteMessage($"Error parsing file: {e.Message}", MessageType.Error);
                return;

            default:
                ConsoleLogger.WriteMessage($"Unexpected error: {e.Message}", MessageType.Error);
                return;
            }
        }
예제 #8
0
        static int Main(string[] args)
        {
            // Parse command-line arguments
            var errorCode = Parser.Default.ParseArguments <GenerateOptions, ParseOptions>(args)
                            .MapResult(
                (GenerateOptions options) => GeneratePattern(options),
                (ParseOptions options) => ParseFontImage(options),
                errs => ErrorCode.ArgumentsNotParsed);

            if (errorCode == ErrorCode.NoError)
            {
                ConsoleLogger.WriteMessage($"SUCCESS! \nFile written: \"{_outputFileName}\"", MessageType.Info);
            }
            else
            {
                NotifyError(errorCode);
            }
            return((int)errorCode);
        }
예제 #9
0
 /// <summary>
 /// Grid pattern generation and writing to file
 /// </summary>
 /// <param name="options">parsed command line args</param>
 /// <returns>error code</returns>
 static int GeneratePattern(GenerateOptions options)
 {
     try
     {
         var settings  = PixelSettings.FromFile(options.PixelSettingsPath);
         var generator = new PatternGenerator(settings);
         var pattern   = generator.GeneratePattern(options.PatternWidth, options.PatternHeight);
         pattern.Save(options.OutputFileName);
     }
     catch (Exception e)
     {
         ConsoleLogger.WriteMessage(e.Message + "\n" + e.InnerException?.Message, MessageType.Error);
         if (e is FileNotFoundException)
         {
             return((int)ErrorCode.FileNotFound);
         }
         return((int)ErrorCode.UknownError);
     }
     return((int)ErrorCode.NoError);
 }
예제 #10
0
        /// <summary>
        /// map all cells in grid to byte arrays
        /// </summary>
        /// <returns>list of mapped arrays</returns>
        public List <byte[]> MapPixels()
        {
            ConsoleLogger.WriteMessage($"Parsing bitmap to byte array", MessageType.Info);
            if (_settings.SymbolWidth * _settings.SymbolHeight * _settings.BitsPerPixel % 8 != 0)
            {
                ConsoleLogger.WriteMessage("Number of bits per symbol is not a multiple of 8. Output values will be padded", MessageType.Warning);
            }

            var symbols = new List <byte[]>();

            for (int j = 0; j < _bitmap.Height; j += _settings.SymbolHeight + _settings.DelimeterHeight)
            {
                for (int i = 0; i < _bitmap.Width; i += _settings.SymbolWidth + _settings.DelimeterWidth)
                {
                    symbols.Add(ProcessSymbol(i, i + _settings.SymbolWidth, j, j + _settings.SymbolHeight));
                }
            }

            return(symbols);
        }
예제 #11
0
 /// <summary>
 /// Opens a filestream and deserialize JSON formatted <see cref="PixelSettings"/>
 /// </summary>
 /// <param name="fileName">Path to file</param>
 /// <returns><see cref="PixelSettings"/> isntance</returns>
 public static PixelSettings FromFile(string fileName)
 {
     try
     {
         using (var stream = File.OpenRead(fileName))
         {
             var serializer = new DataContractJsonSerializer(typeof(PixelSettings), new DataContractJsonSerializerSettings()
             {
                 UseSimpleDictionaryFormat = true
             });
             ConsoleLogger.WriteMessage($"Loaded configuration from {stream.Name}", MessageType.Info);
             return(serializer.ReadObject(stream) as PixelSettings);
         }
     }
     catch (IOException e)
     {
         ConsoleLogger.WriteMessage("Error reading from config file", MessageType.Error);
         ConsoleLogger.WriteMessage(e.Message, MessageType.Error);
         throw;
     }
 }
예제 #12
0
        /// <summary>
        /// map all cells in grid to byte arrays
        /// </summary>
        /// <param name="skipHeaders">will skip first row and first column</param>
        /// <returns>list of mapped arrays</returns>
        public List <byte[]> MapPixels(bool skipHeaders)
        {
            ConsoleLogger.WriteMessage($"Parsing bitmap to byte array", MessageType.Info);
            if (_settings.SymbolWidth * _settings.SymbolHeight * _settings.BitsPerPixel % 8 != 0)
            {
                ConsoleLogger.WriteMessage("Number of bits per symbol is not a multiple of 8. Output values will be padded", MessageType.Warning);
            }

            var symbols = new List <byte[]>();

            var columnCount = (_bitmap.Width + _settings.DelimeterWidth) /
                              (_settings.SymbolWidth + _settings.DelimeterWidth);
            var rowCount = (_bitmap.Height + _settings.DelimeterHeight) /
                           (_settings.SymbolHeight + _settings.DelimeterHeight);

            var pixelTracker = new BitmapPixelTracker(_settings.CellsLookupDirection)
            {
                // Skip first row and columnt if they were used for rows/columns numbers
                XStart = skipHeaders ? 1 : 0,
                XEnd   = columnCount,
                XDelta = 1,
                // Skip first row and columnt if they were used for rows/columns numbers
                YStart = skipHeaders ? 1 : 0,
                YEnd   = rowCount,
                YDelta = 1
            };

            // Process cells (symbols)
            // in this case pixel coords will correspond to cell
            foreach (var pixel in pixelTracker)
            {
                // get symbol top leftPoint
                var symbolX = pixel.X * (_settings.DelimeterWidth + _settings.SymbolWidth);
                var symbolY = pixel.Y * (_settings.DelimeterHeight + _settings.SymbolHeight);
                symbols.Add(ProcessSymbol(symbolX, symbolX + _settings.SymbolWidth, symbolY, symbolY + _settings.SymbolHeight));
            }

            return(symbols);
        }
예제 #13
0
        /// <summary>
        /// Grid pattern generation and writing to file
        /// </summary>
        /// <param name="options">parsed command line args</param>
        /// <returns>error code</returns>
        static ErrorCode GeneratePattern(GenerateOptions options)
        {
            try
            {
                if (options.ExcessValue != null)
                {
                    return(ErrorCode.ArgumentsMismatch);
                }

                Settings        = PixelSettings.FromFile(options.PixelSettingsPath);
                _outputFileName = options.OutputFileName;

                var    generator  = new PatternGenerator(Settings);
                byte[] sampleData = null;
                if (options.InputFileName != null)
                {
                    sampleData = ParseDataFile(options.InputFileName);
                }
                var pattern = generator.GeneratePattern(options.PatternWidth,
                                                        options.PatternHeight, options.EnumerationStyle, sampleData);
                pattern.Save(options.OutputFileName);
            }
            catch (Exception e)
            {
                switch (e)
                {
                case PixelProcessingException _:
                    ConsoleLogger.WriteMessage(e.Message, MessageType.Error);
                    return(ErrorCode.FileParsingError);

                case FileNotFoundException _:
                    return(ErrorCode.FileNotFound);

                default:
                    return(ErrorCode.UknownError);
                }
            }
            return(ErrorCode.NoError);
        }
예제 #14
0
        /// <summary>
        /// Writes formatted output of symbols parser's result
        /// </summary>
        /// <param name="symbols">byte[] representation of symbols</param>
        /// <param name="fileName">path to the file to create</param>
        /// <param name="singleArray">shall output be written to single array or one array per symbol</param>
        public static void WriteOutput(List <byte[]> symbols, string fileName, bool singleArray = false)
        {
            try
            {
                using (var stream = File.Open(fileName, FileMode.Create))
                    using (var writer = new StreamWriter(stream))
                    {
                        // Make header
                        writer.WriteLine("//");
                        writer.WriteLine("//");
                        writer.WriteLine("// Generated with PixelPixie (c) 2016");
                        writer.WriteLine("//");
                        writer.WriteLine("//");
                        writer.WriteLine();
                        writer.WriteLine();

                        // Write array(s)
                        if (singleArray)
                        {
                            var totalLength = (from s in symbols
                                               select s.Length).Sum();

                            writer.Write($"unsigned char c[{totalLength}] = \n");
                            writer.Write("{\n    ");

                            int elementCounter = 0;

                            for (int i = 0; i < symbols.Count; i++)
                            {
                                for (int j = 0; j < symbols[i].Length; j++)
                                {
                                    writer.Write($"0x{symbols[i][j]:X2}");
                                    elementCounter++;
                                    if (j + 1 < symbols[i].Length || i < symbols.Count - 1)
                                    {
                                        writer.Write(", ");
                                        if (elementCounter % ElementsPerLine == ElementsPerLine - 1)
                                        {
                                            writer.Write("\n    ");
                                        }
                                    }
                                }
                            }
                            writer.Write("\n};");
                            writer.WriteLine("\n");
                        }
                        else
                        {
                            for (int i = 0; i < symbols.Count; i++)
                            {
                                writer.WriteLine($"//symbol {i + 1}");
                                writer.Write($"unsigned char c{i + 1}[{symbols[i].Length}] = \n");
                                writer.Write("{\n    ");
                                for (int j = 0; j < symbols[i].Length; j++)
                                {
                                    writer.Write($"0x{symbols[i][j]:X2}");
                                    if (j + 1 < symbols[i].Length)
                                    {
                                        writer.Write(", ");
                                        if (j % ElementsPerLine == ElementsPerLine - 1)
                                        {
                                            writer.Write("\n    ");
                                        }
                                    }
                                }
                                writer.Write("\n};");
                                writer.WriteLine("\n");
                            }
                        }
                    }
            }
            catch (IOException)
            {
                ConsoleLogger.WriteMessage("Failed writing output", MessageType.Error);
                throw;
            }
        }
예제 #15
0
        /// <summary>
        /// Writes formatted output of symbols parser's result
        /// </summary>
        /// <param name="symbols">byte[] representation of symbols</param>
        /// <param name="fileName">path to the file to create</param>
        /// <param name="singleArray">shall output be written to single array or one array per symbol</param>
        /// <param name="contentOnly">for single array: output will be just array contents, without name or curly braces</param>
        public static void WriteOutput(List <byte[]> symbols, string fileName, bool singleArray = false, bool contentOnly = false)
        {
            try
            {
                using (var stream = File.Open(fileName, FileMode.Create))
                    using (var writer = new StreamWriter(stream))
                    {
                        var fileVersionInfo = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);
                        var copyRight       = fileVersionInfo.LegalCopyright;
                        var version         = fileVersionInfo.ProductVersion;
                        // Make header
                        writer.WriteLine("//");
                        writer.WriteLine("//");
                        writer.WriteLine($"// Generated with PixelPixie v.{version} {copyRight}");
                        writer.WriteLine("//");
                        writer.WriteLine("//");
                        writer.WriteLine();
                        writer.WriteLine();

                        // Write array(s)
                        if (singleArray)
                        {
                            var totalLength = (from s in symbols
                                               select s.Length).Sum();

                            if (contentOnly == false)
                            {
                                writer.Write($"unsigned char c[{totalLength}] = \n");
                                writer.Write("{\n    ");
                            }
                            else
                            {
                                writer.Write("    ");
                            }

                            int elementCounter = 0;

                            for (int i = 0; i < symbols.Count; i++)
                            {
                                for (int j = 0; j < symbols[i].Length; j++)
                                {
                                    writer.Write($"0x{symbols[i][j]:X2}");
                                    elementCounter++;
                                    if (j + 1 < symbols[i].Length || i < symbols.Count - 1)
                                    {
                                        writer.Write(", ");
                                        if (elementCounter % ElementsPerLine == ElementsPerLine - 1)
                                        {
                                            writer.Write("\n    ");
                                        }
                                    }
                                }
                            }

                            if (contentOnly == false)
                            {
                                writer.Write("\n};");
                            }

                            writer.WriteLine("\n");
                        }
                        else
                        {
                            for (int i = 0; i < symbols.Count; i++)
                            {
                                writer.WriteLine($"//symbol {i + 1}");
                                writer.Write($"unsigned char c{i + 1}[{symbols[i].Length}] = \n");
                                writer.Write("{\n    ");
                                for (int j = 0; j < symbols[i].Length; j++)
                                {
                                    writer.Write($"0x{symbols[i][j]:X2}");
                                    if (j + 1 < symbols[i].Length)
                                    {
                                        writer.Write(", ");
                                        if (j % ElementsPerLine == ElementsPerLine - 1)
                                        {
                                            writer.Write("\n    ");
                                        }
                                    }
                                }
                                writer.Write("\n};");
                                writer.WriteLine("\n");
                            }
                        }
                    }
            }
            catch (IOException)
            {
                ConsoleLogger.WriteMessage("Failed writing output", MessageType.Error);
                throw;
            }
        }