//Сжатие с использование квадродеревьев public static void Compression(string filename, string quality) { if (!(File.Exists(filename))) { System.Console.WriteLine("Файла не существует"); return; } //Черно-белый файл или нет if (quality == "Black") { colorflag = 1; } else { if (quality == "Color") { colorflag = 3; } else { System.Console.WriteLine("Тип выбран не правильно"); return; } } Bitmap image = new Bitmap(filename); imageWidth = image.Width; imageHeigth = image.Height; classImageColor = new Color[image.Width, image.Height]; for (int i = 0; i < image.Width; ++i) { for (int j = 0; j < image.Height; ++j) { classImageColor[i, j] = image.GetPixel(i, j); } } brightnessImage = new double[image.Width, image.Height]; for (int i = 0; i < image.Width; ++i) { for (int j = 0; j < image.Height; ++j) { brightnessImage[i, j] = image.GetPixel(i, j).GetBrightness(); } } //Создаём ранговое дерево range_block_size = 64; range_num_width = image.Width / range_block_size; range_num_height = image.Height / range_block_size; rangeArray = new Object.Block[range_num_width, range_num_height]; //Изначально создаются ранговые блоки, на основе которых будут составляться деревья for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { rangeArray[i, j] = CreateBlockRange(i * range_block_size, j * range_block_size, classImageColor, range_block_size, brightnessImage); } } rangeTree = new BlockTree[range_num_width, range_num_height]; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { numLock = 1; rangeTree[i, j] = new BlockTree(rangeArray[i, j], rangeArray[i, j].BlockSize); } } //Доменные блоки представлены не в виде деревьев, а в виде трехмерных массивов domain_num_width = range_num_width - 1; domain_num_height = range_num_height - 1; domain_block_size = range_block_size * 2; domainArray = new Object.Block[domain_num_width, domain_num_height]; //System.Console.WriteLine(DomainBlocks.Length); domainBlocks = new Object.BlockArray[PostProcessing.GetPow(domain_block_size)]; for (int i = 0; i < domainBlocks.Length; ++i) { if (i == 0) { domainBlocks[i].BlockSize = domain_block_size; } else { domainBlocks[i].BlockSize = domainBlocks[i - 1].BlockSize / 2; } domainBlocks[i].num_width = image.Width / domainBlocks[i].BlockSize; domainBlocks[i].num_height = image.Height / domainBlocks[i].BlockSize; domainBlocks[i].Blocks = new Object.Block[domainBlocks[i].num_width, domainBlocks[i].num_height]; for (int j = 0; j < domainBlocks[i].num_width; ++j) { for (int k = 0; k < domainBlocks[i].num_height; ++k) { domainBlocks[i].Blocks[j, k] = CreateBlockDomain(j * domainBlocks[i].BlockSize / 2, k * domainBlocks[i].BlockSize / 2, classImageColor, domainBlocks[i].BlockSize / 2, brightnessImage); } } } listCoeff = new List <Object.Coefficients>(); //Обход всех деревьев и нахождение для нужных коэффициентов преобразования, а так же выписывание их в файл for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { blockChecker = 0; rangeTree[i, j].RoundTree(rangeTree[i, j], domainBlocks, classImageColor, rangeTree[i, j].mainBlock.BlockSize); } } bw = new BinaryWriter(File.Open(@"C:\Users\Admin\Documents\GitHub\Fractal-Compression\NewFractalCompression\NewFractalCompression\Quad Compression", FileMode.Create)); bw.Write(MyConverter.Convert(BitConverter.GetBytes(image.Width), 2)); bw.Write(MyConverter.Convert(BitConverter.GetBytes(image.Height), 2)); bw.Write(MyConverter.Convert(BitConverter.GetBytes(range_block_size), 1)); bw.Write(MyConverter.Convert(BitConverter.GetBytes(listCoeff.Count), 4)); //for (int i = 0; i < range_num_width; ++i) //{ // for (int j = 0; j < range_num_height; ++j) // { // rangeTree[i, j].PrintTree(rangeTree[i, j], 0); // } //} for (int i = 0; i < listCoeff.Count; ++i) { //Запись в файл всех нужные чисел, а так же глубину нахождения узла в дереве Byte[] D = BitConverter.GetBytes(listCoeff[i].Depth); Byte[] X = BitConverter.GetBytes(listCoeff[i].X); Byte[] Y = BitConverter.GetBytes(listCoeff[i].Y); Byte[] SR = BitConverter.GetBytes(listCoeff[i].shiftR); Byte[] SG = BitConverter.GetBytes(listCoeff[i].shiftG); Byte[] SB = BitConverter.GetBytes(listCoeff[i].shiftB); //System.Console.WriteLine(listCoeff[i].Depth + " -- " + D[0]); bw.Write(MyConverter.Convert(D, 1)); bw.Write(MyConverter.Convert(X, 1)); bw.Write(MyConverter.Convert(Y, 1)); bw.Write(MyConverter.Convert(SR, 2)); bw.Write(MyConverter.Convert(SG, 2)); bw.Write(MyConverter.Convert(SB, 2)); } bw.Close(); }
public static void ColorDecompression() { byte[] BytesFile = File.ReadAllBytes(@"C:\Users\Admin\Documents\GitHub\Fractal-Compression\NewFractalCompression\NewFractalCompression\Compression"); int fileCount = 0; //Коэффициент масштабирования int scale = 1; Byte[] tmp = MyConverter.ReadByte(BytesFile, 0, 2); int Image_width = BitConverter.ToInt16(tmp, 0) * scale; fileCount += 2; tmp = MyConverter.ReadByte(BytesFile, 2, 4); int Image_height = BitConverter.ToInt16(tmp, 0) * scale; fileCount += 2; tmp = MyConverter.ReadByte(BytesFile, 4, 5); int range_block_size = tmp[0] * scale; fileCount += 1; Bitmap newImage = new Bitmap(Image_width, Image_height); int range_num_width = newImage.Width / range_block_size; int range_num_height = newImage.Height / range_block_size; compressCoeff = new Object.Coefficients[range_num_width, range_num_height, 1]; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { tmp = MyConverter.ReadByte(BytesFile, fileCount, fileCount + 1); compressCoeff[i, j, 0].X = tmp[0]; fileCount += 1; tmp = MyConverter.ReadByte(BytesFile, fileCount, fileCount + 1); compressCoeff[i, j, 0].Y = tmp[0]; fileCount += 1; tmp = MyConverter.ReadByte(BytesFile, fileCount, fileCount + 2); compressCoeff[i, j, 0].shiftR = BitConverter.ToInt16(tmp, 0); fileCount += 2; tmp = MyConverter.ReadByte(BytesFile, fileCount, fileCount + 2); compressCoeff[i, j, 0].shiftG = BitConverter.ToInt16(tmp, 0); fileCount += 2; tmp = MyConverter.ReadByte(BytesFile, fileCount, fileCount + 2); compressCoeff[i, j, 0].shiftB = BitConverter.ToInt16(tmp, 0); fileCount += 2; } } //Создаём ранговые блоки Object.Block[,] rangeArray = new Object.Block[range_num_width, range_num_height]; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { rangeArray[i, j].X = i * range_block_size; rangeArray[i, j].Y = j * range_block_size; } } //Создаем доменные блоки int domain_num_width = range_num_width - 1; int domain_num_height = range_num_height - 1; int domain_block_size = range_block_size * 2; Object.Block[,] domainArray = new Object.Block[domain_num_width, domain_num_height]; for (int i = 0; i < domain_num_width; ++i) { for (int j = 0; j < domain_num_height; ++j) { domainArray[i, j].X = i * range_block_size; domainArray[i, j].Y = j * range_block_size; } } for (int it = 0; it < 10; ++it) { Color[,] newImageColor = new Color[newImage.Width, newImage.Height]; for (int i = 0; i < newImage.Width; ++i) { for (int j = 0; j < newImage.Height; ++j) { newImageColor[i, j] = newImage.GetPixel(i, j); } } Color[,] rotateNewImageR = newImageColor; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { Object.Block rangeBlock = rangeArray[i, j]; Object.Coefficients current_coefficentR = compressCoeff[i, j, 0]; Object.Block domainBlockR = domainArray[current_coefficentR.X, current_coefficentR.Y]; for (int pix_x = 0; pix_x < range_block_size; ++pix_x) { for (int pix_y = 0; pix_y < range_block_size; ++pix_y) { Color colorR1 = rotateNewImageR[domainBlockR.X + (pix_x), domainBlockR.Y + (pix_y)]; Color colorR = rotateNewImageR[domainBlockR.X + (pix_x * 2), domainBlockR.Y + (pix_y * 2)]; //int R = (int)(U * ((colorR.R + colorR1.R) / 2) + (Current_coefficentR.shiftR)); int r = (int)(u * colorR.R + (current_coefficentR.shiftR)); if (r < 0) { r = 0; } if (r > 255) { r = 255; } Color colorG1 = rotateNewImageR[domainBlockR.X + (pix_x), domainBlockR.Y + (pix_y)]; Color colorG = rotateNewImageR[domainBlockR.X + (pix_x * 2), domainBlockR.Y + (pix_y * 2)]; //int G = (int)(U * ((colorG.G + colorG1.G) / 2) + (Current_coefficentR.shiftG)); int g = (int)(u * colorG.G + (current_coefficentR.shiftG)); if (g < 0) { g = 0; } if (g > 255) { g = 255; } Color colorB1 = rotateNewImageR[domainBlockR.X + (pix_x), domainBlockR.Y + (pix_y)]; Color colorB = rotateNewImageR[domainBlockR.X + (pix_x * 2), domainBlockR.Y + (pix_y * 2)]; //int B = (int)(U * ((colorB.B + colorB1.B) / 2) + (Current_coefficentR.shiftB)); int b = (int)(u * colorB.B + (current_coefficentR.shiftB)); if (b < 0) { b = 0; } if (b > 255) { b = 255; } Color Newcolor = Color.FromArgb(r, g, b); newImage.SetPixel(rangeBlock.X + pix_x, rangeBlock.Y + pix_y, Newcolor); } } } } } newImage.Save(@"C:\Users\Admin\Documents\GitHub\Fractal-Compression\NewFractalCompression\NewFractalCompression\Expanded file.bmp", System.Drawing.Imaging.ImageFormat.Bmp); }
static public void Decompression() { System.Console.WriteLine("Decompression dont work"); return; byte[] bytesFile = File.ReadAllBytes(@"C:\Users\dbogdano\Documents\GitHub\Fractal-Compression\NewFractalCompression\NewFractalCompression\Quad Compression"); int fileCount = 0; //Коэффициент масштабирования int scale = 1; Byte[] tmp = MyConverter.ReadByte(bytesFile, 0, 2); int image_width = BitConverter.ToInt16(tmp, 0) * scale; //+ fileCount += 2; tmp = MyConverter.ReadByte(bytesFile, 2, 4); int image_height = BitConverter.ToInt16(tmp, 0) * scale; //+ fileCount += 2; tmp = MyConverter.ReadByte(bytesFile, 4, 5); int range_block_size = tmp[0] * scale; //+ fileCount += 1; tmp = MyConverter.ReadByte(bytesFile, 5, 9); fileCount += 4; int listSize = BitConverter.ToInt32(tmp, 0); Bitmap newImage = new Bitmap(image_width, image_height); Color[,] newImageColor = new Color[newImage.Width, newImage.Height]; brightnessImage = new double[newImage.Width, newImage.Height]; for (int i = 0; i < newImage.Width; ++i) { for (int j = 0; j < newImage.Height; ++j) { brightnessImage[i, j] = newImage.GetPixel(i, j).GetBrightness(); } } int range_num_width = newImage.Width / range_block_size; int range_num_height = newImage.Height / range_block_size; Object.Block[,] newRangeArray = new Object.Block[range_num_width, range_num_height]; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { newRangeArray[i, j].X = i * range_block_size; newRangeArray[i, j].Y = j * range_block_size; } } rangeTree = new BlockTree[range_num_width, range_num_height]; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { numLock = 1; rangeTree[i, j] = new BlockTree(newRangeArray[i, j], newRangeArray[i, j].BlockSize); } } //Доменные блоки представлены не в виде деревьев, а в виде трехмерных массивов domain_num_width = range_num_width - 1; domain_num_height = range_num_height - 1; domain_block_size = range_block_size * 2; domainArray = new Object.Block[domain_num_width, domain_num_height]; //System.Console.WriteLine(DomainBlocks.Length); domainBlocks = new Object.BlockArray[PostProcessing.GetPow(domain_block_size)]; for (int i = 0; i < domainBlocks.Length; ++i) { if (i == 0) { domainBlocks[i].BlockSize = domain_block_size; } else { domainBlocks[i].BlockSize = domainBlocks[i - 1].BlockSize / 2; } domainBlocks[i].num_width = newImage.Width / domainBlocks[i].BlockSize; domainBlocks[i].num_height = newImage.Height / domainBlocks[i].BlockSize; domainBlocks[i].Blocks = new Object.Block[domainBlocks[i].num_width, domainBlocks[i].num_height]; for (int j = 0; j < domainBlocks[i].num_width; ++j) { for (int k = 0; k < domainBlocks[i].num_height; ++k) { domainBlocks[i].Blocks[j, k] = CreateBlockDomain(j * domainBlocks[i].BlockSize / 2, k * domainBlocks[i].BlockSize / 2, newImageColor, domainBlocks[i].BlockSize / 2, brightnessImage); } } } List <Object.Coefficients> listCoeff = new List <Object.Coefficients>(); Object.Coefficients coeff = new Object.Coefficients(); for (int i = 0; i < listSize; ++i) { tmp = MyConverter.ReadByte(bytesFile, fileCount, fileCount + 1); coeff.Depth = tmp[0]; ++fileCount; tmp = MyConverter.ReadByte(bytesFile, fileCount, fileCount + 1); coeff.X = tmp[0]; fileCount += 1; tmp = MyConverter.ReadByte(bytesFile, fileCount, fileCount + 1); coeff.Y = tmp[0]; fileCount += 1; tmp = MyConverter.ReadByte(bytesFile, fileCount, fileCount + 2); coeff.shiftR = BitConverter.ToInt16(tmp, 0); fileCount += 2; tmp = MyConverter.ReadByte(bytesFile, fileCount, fileCount + 2); coeff.shiftG = BitConverter.ToInt16(tmp, 0); fileCount += 2; tmp = MyConverter.ReadByte(bytesFile, fileCount, fileCount + 2); coeff.shiftB = BitConverter.ToInt16(tmp, 0); fileCount += 2; listCoeff.Add(coeff); } int blI = 0, blJ = -1; for (int i = 0; i < listCoeff.Count; ++i) { PrintCoefficients(listCoeff[i]); } for (int i = 0; i < listCoeff.Count; ++i) { if (listCoeff[i].Depth < 0) { ++blJ; if (blJ == range_num_height) { ++blI; blJ = 0; } } rangeTree[blI, blJ].AddCoeff(rangeTree[blI, blJ], listCoeff[i]); } //Построение изображения из деревьев for (int i = 0; i < 10; ++i) { for (int j = 0; j < range_num_width; ++j) { for (int k = 0; k < range_num_height; ++k) { rangeTree[j, k].DrawTree(rangeTree[j, k], domainBlocks, newImageColor); } } } for (int j = 0; j < newImage.Width; ++j) { for (int k = 0; k < newImage.Height; ++k) { newImage.SetPixel(j, k, newImageColor[j, k]); } } newImage.Save(@"C:\Users\dbogdano\Documents\GitHub\Fractal-Compression\NewFractalCompression\NewFractalCompression\Quad file.bmp", System.Drawing.Imaging.ImageFormat.Bmp); }
public static void Compression(string filename, string quality) { if (!(File.Exists(filename))) { System.Console.WriteLine("Файла не существует"); return; } //Черно-белый файл или нет if (quality == "Black") { colorflag = 1; } else { if (quality == "Color") { colorflag = 3; } else { System.Console.WriteLine("Тип выбран не правильно"); return; } } Bitmap image = new Bitmap(filename); classImageColor = new Color[image.Width, image.Height]; for (int i = 0; i < image.Width; ++i) { for (int j = 0; j < image.Height; ++j) { classImageColor[i, j] = image.GetPixel(i, j); } } double[,] BrightnessImage = new double[image.Width, image.Height]; for (int i = 0; i < image.Width; ++i) { for (int j = 0; j < image.Height; ++j) { BrightnessImage[i, j] = image.GetPixel(i, j).GetBrightness(); } } //Основной параметр, отвечающий за размеры ранговых блоков range_block_size = 128; //Создаём ранговые блоки range_num_width = image.Width / range_block_size; range_num_height = image.Height / range_block_size; rangeArray = new Object.Block[range_num_width, range_num_height]; for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { rangeArray[i, j] = CreateBlockRange(i * range_block_size, j * range_block_size, classImageColor, range_block_size, BrightnessImage); } } //Создаем доменные блоки domain_num_width = range_num_width - 1; domain_num_height = range_num_height - 1; domain_block_size = range_block_size * 2; domainArray = new Object.Block[domain_num_width, domain_num_height]; for (int i = 0; i < domain_num_width; ++i) { for (int j = 0; j < domain_num_height; ++j) { domainArray[i, j] = CreateBlockDomain(i * range_block_size, j * range_block_size, classImageColor, range_block_size, BrightnessImage); } } //Алгоритм сжатия count = 1; //Общеее число преобразований block_all_num = colorflag * range_num_width * range_num_height; compressCoeff = new Object.Coefficients[range_num_width, range_num_height, 1]; BinaryWriter bw = new BinaryWriter(File.Open(@"C:\Users\Admin\Documents\GitHub\Fractal-Compression\NewFractalCompression\NewFractalCompression\Compression", FileMode.Create)); Parallel.For(0, range_num_width, FindCoefficients); //Выводим коэффиценты в файл bw.Write(MyConverter.Convert(BitConverter.GetBytes(image.Width), 2)); bw.Write(MyConverter.Convert(BitConverter.GetBytes(image.Height), 2)); bw.Write(MyConverter.Convert(BitConverter.GetBytes(range_block_size), 1)); for (int k = 0; k < 1; ++k) { for (int i = 0; i < range_num_width; ++i) { for (int j = 0; j < range_num_height; ++j) { Byte[] X = BitConverter.GetBytes(compressCoeff[i, j, k].X); Byte[] Y = BitConverter.GetBytes(compressCoeff[i, j, k].Y); Byte[] SR = BitConverter.GetBytes(compressCoeff[i, j, k].shiftR); Byte[] SG = BitConverter.GetBytes(compressCoeff[i, j, k].shiftG); Byte[] SB = BitConverter.GetBytes(compressCoeff[i, j, k].shiftB); bw.Write(MyConverter.Convert(X, 1)); bw.Write(MyConverter.Convert(Y, 1)); bw.Write(MyConverter.Convert(SR, 2)); bw.Write(MyConverter.Convert(SG, 2)); bw.Write(MyConverter.Convert(SB, 2)); } } } bw.Close(); }