// Разбить this.image на блоки, покрасить их в рандомные цвета и вывести в view.Image2
        public void showBlocks()
        {
            if (imageValues == null)
            {
                return;
            }

            //бьем изображение на блоки
            var blockSize = view.BlockSize;
            var blocks    = ImageUtils.splitImageValuesIntoBlocks(imageValues, image.Width, image.Height, blockSize);

            //каждый блок красим в рандомный цвет
            Random random = new Random();

            Parallel.For(0, blocks.Length, i =>
            {
                float color = (float)random.NextDouble() * 255f;
                for (int j = 0; j < blocks[i].Length; ++j)
                {
                    blocks[i][j] = color;
                }
            });

            //собираем блоки обратно в изображение
            float[] resultValues = ImageUtils.mergeBlocksToImageValues(blocks, image.Width, image.Height, blockSize);

            //если есть остаток - то дописываем его
            var remainderSize = ImageUtils.getRemainderSize(image.Width, image.Height, blockSize);

            if (remainderSize != 0)
            {
                var remainder = ImageUtils.getRemainder(imageValues, image.Width, image.Height, blockSize);
                ImageUtils.writeRemainderIntoImageValues(remainder, resultValues, image.Width, image.Height, blockSize);
            }

            //выводим результат
            var resultImage = ImageUtils.ConvertValuesToImage(resultValues, view.ColorScheme, image.Width, image.Height);

            view.Image2 = resultImage;

            //выводим информацию
            var temp = ImageUtils.getBlocksAmount(blockSize, image.Width, image.Height);
            var blocksAmountHorisontal = temp.Item1;
            var blocksAmountVertical   = temp.Item2;
            var totalBlocksAmount      = blocks.Length;

            view.Info = string.Format(
                "Всего {0} блоков\n" +
                "{1} по горизонтали и {2} по вертикали\n" +
                "С остатком в {3} пикселей",
                totalBlocksAmount,
                blocksAmountHorisontal, blocksAmountVertical,
                remainderSize
                );
        }
        // Разбить this.image на блоки, посчитать их спектры и вывести в view.Image2
        public void showSpectre(bool brighter = false)
        {
            if (imageValues == null)
            {
                return;
            }

            var t1 = CurrentTime();

            //бьем изображение на блоки
            var blockSize = view.BlockSize;
            var blocks    = ImageUtils.splitImageValuesIntoBlocks(imageValues, image.Width, image.Height, blockSize);

            //применяем прямое преобразоваение к каждому блоку
            switch (view.Method)
            {
            case "FHT":
                MathUtils.mapFunctionToEachBlock(MathUtils.fht_2d, blocks);
                break;

            case "DCT":
                MathUtils.mapFunctionToEachBlock(MathUtils.dct_2d, blocks);
                break;
            }

            //собираем блоки обратно в изображение
            float[] resultValues = ImageUtils.mergeBlocksToImageValues(blocks, image.Width, image.Height, blockSize);

            if (brighter)
            {
                //увеличиваем яркость, что бы на проекторе лучше было видно
                Parallel.For(0, resultValues.Length, i =>
                {
                    resultValues[i] *= 20;
                });
            }

            //если есть остаток - то дописываем его
            long remainderSize = ImageUtils.getRemainderSize(image.Width, image.Height, blockSize);

            if (remainderSize != 0)
            {
                float[] remainder = ImageUtils.getRemainder(imageValues, image.Width, image.Height, blockSize);
                ImageUtils.writeRemainderIntoImageValues(remainder, resultValues, image.Width, image.Height, blockSize);
            }

            //выводим результат
            Image resultImage = ImageUtils.ConvertValuesToImage(resultValues, "RGB", image.Width, image.Height);
            var   t2          = CurrentTime();

            view.Image2 = resultImage;

            //выводим информацию
            var temp = ImageUtils.getBlocksAmount(blockSize, image.Width, image.Height);
            var blocksAmountHorisontal = temp.Item1;
            var blocksAmountVertical   = temp.Item2;
            var totalBlocksAmount      = blocks.Length;

            view.Info = string.Format(
                "Готово за {0} секунд\n" +
                "Всего {1} блоков\n" +
                "{2} по горизонтали и {3} по вертикали\n" +
                "С остатком в {4} пикселей",
                (t2 - t1) / 1000f,
                totalBlocksAmount,
                blocksAmountHorisontal, blocksAmountVertical,
                remainderSize
                );
        }