public static RGBImage FitToBlockSize(RGBImage image, int blockSize) { int oldHeight = image.Height; int oldWidth = image.Width; int newHeight = (int)Math.Ceiling((float)image.Height / blockSize); newHeight *= blockSize; int newWidth = (int)Math.Ceiling((float)image.Width / blockSize); newWidth *= blockSize; if (oldHeight == newHeight && oldWidth == newWidth) { return(image); } var oldPixels = image.Pixels; var newPixels = new RGBPixel[newWidth, newHeight]; var stubPixel = new RGBPixel(0, 0, 0); for (var i = 0; i < newWidth; i++) { for (var j = 0; j < newHeight; j++) { if (i < oldWidth && j < oldHeight) { newPixels[i, j] = oldPixels[i, j]; } else { newPixels[i, j] = stubPixel; } } } return(new RGBImage(newPixels)); }
private Image BeginHaarCompress() { Timer timer = Timer.GetInstance(); timer.Clear(); int p = int.Parse(p_textBox.Text); if (!TransformsUtils.haarMatrixes.ContainsKey(p)) { TransformsUtils.BuildHaarMatrix(p); } blockSize = (int)Math.Pow(p, int.Parse(N_textBox.Text)); var chunkSize = blockSize * 2; var originalWidth = sourceImageBox.Image.Width; var originalHeight = sourceImageBox.Image.Height; var rgbImage = new RGBImage(sourceImageBox.Image); var fittedToChunksImage = ImageUtils.FitToBlockSize(rgbImage, chunkSize); var chunks = fittedToChunksImage.ToBlockArray(chunkSize, out int widthBlocks, out int heightBlocks); var haarChunks = new HaarChunk[chunks.Length]; var parallelOptions = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; timer.Start(MAIN, TRANSFORM); var flag = Parallel.ForEach(chunks, parallelOptions, (elem, loopState, elementIndex) => { var haarChunk = new HaarChunk(new Chunk(chunks[elementIndex], blockSize), p); haarChunk.ZeroCoeffs(zeroPercentY, zeroPercentCb, zeroPercentCr); haarChunks[elementIndex] = haarChunk; }); while (!flag.IsCompleted) { ; } timer.End(MAIN, TRANSFORM); foreach (HaarChunk chunk in haarChunks) { coeffsCount += chunk.CoeffsCount(); zeroCoeffsCount += chunk.ZeroCoeffsCount(); } var listOfDecompressedImages = new YCbCrImage[haarChunks.Length]; var listOfDecompressedChunks = new Chunk[haarChunks.Length]; var matrix = new YCbCrImage[widthBlocks, heightBlocks]; timer.Start(MAIN, REVERSE_TRANSFORM); flag = Parallel.ForEach(haarChunks, parallelOptions, (elem, loopState, i) => { listOfDecompressedChunks[i] = new Chunk(haarChunks[i], p); listOfDecompressedImages[i] = YCbCrImage.FromChunk(listOfDecompressedChunks[i]); var j = i / widthBlocks; matrix[i - j * widthBlocks, j] = listOfDecompressedImages[i]; }); while (!flag.IsCompleted) { ; } timer.End(MAIN, REVERSE_TRANSFORM); timer.DisplayIntervals(); var decompressedImage = YCbCrImage.FromMatrix(matrix).ToRGBImage(originalWidth, originalHeight); return(decompressedImage.ToImage()); }
private Image BeginVilenkinCompress() { p = new List <int>(); ArrayUtils.Fill(p, int.Parse(p_textBox.Text), 30); Timer timer = Timer.GetInstance(); timer.Clear(); if (vilenkin == null) { timer.Start(MAIN, PREPARATION); vilenkin = new VilenkinTransform(p, int.Parse(N_textBox.Text) - 1); timer.End(MAIN, PREPARATION); } blockSize = vilenkin.GetBlockSize(); chunkSize = blockSize * 2; var originalWidth = sourceImageBox.Image.Width; var originalHeight = sourceImageBox.Image.Height; var rgbImage = new RGBImage(sourceImageBox.Image); var fittedToChunksImage = ImageUtils.FitToBlockSize(rgbImage, chunkSize); var chunks = fittedToChunksImage.ToBlockArray(chunkSize, out int widthBlocks, out int heightBlocks); var vilenkinChunks = new VilenkinChunk[chunks.Length]; var parallelOptions = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; timer.Start(MAIN, TRANSFORM); var flag = Parallel.ForEach(chunks, parallelOptions, (elem, loopState, elementIndex) => { var vilenkinChunk = new VilenkinChunk(vilenkin, new Chunk(chunks[elementIndex], blockSize)); vilenkinChunk.ZeroCoeffs(zeroPercentY, zeroPercentCb, zeroPercentCr); vilenkinChunks[elementIndex] = vilenkinChunk; }); while (!flag.IsCompleted) { ; } timer.End(MAIN, TRANSFORM); foreach (VilenkinChunk chunk in vilenkinChunks) { coeffsCount += chunk.CoeffsCount(); zeroCoeffsCount += chunk.ZeroCoeffsCount(); } var listOfDecompressedImages = new YCbCrImage[vilenkinChunks.Length]; var listOfDecompressedChunks = new Chunk[vilenkinChunks.Length]; var matrix = new YCbCrImage[widthBlocks, heightBlocks]; timer.Start(MAIN, REVERSE_TRANSFORM); flag = Parallel.ForEach(vilenkinChunks, parallelOptions, (elem, loopState, i) => { listOfDecompressedChunks[i] = new Chunk(vilenkinChunks[i], vilenkin); listOfDecompressedImages[i] = YCbCrImage.FromChunk(listOfDecompressedChunks[i]); var j = i / widthBlocks; matrix[i - j * widthBlocks, j] = listOfDecompressedImages[i]; }); while (!flag.IsCompleted) { ; } timer.End(MAIN, REVERSE_TRANSFORM); timer.DisplayIntervals(); var decompressedImage = YCbCrImage.FromMatrix(matrix).ToRGBImage(originalWidth, originalHeight); return(decompressedImage.ToImage()); }
public Image Compress(float quantCoeffCbCrDC, float quantCoeffCbCrAC, bool yQuantEnabled, float quantCoeffYDC, float quantCoeffYAC, int blockSize, out int coeffsCount, out int zeroCoeffsCount, int percentY, int percentCb, int percentCr) { BLOCK_SIZE = blockSize; CHUNK_SIZE = blockSize * 2; coeffsCount = 0; zeroCoeffsCount = 0; Timer timer = Timer.GetInstance(); timer.Clear(); timer.Start(MAIN_ID, FULL_COMPRESS); timer.Start(SUB_ID, PREP); var originalWidth = sourceImage.Width; var originalHeight = sourceImage.Height; timer.Start(SUB_ID, TO_RGB_IMAGE); var rgbImage = new RGBImage(sourceImage); timer.End(SUB_ID, TO_RGB_IMAGE); timer.Start(SUB_ID, FITTING); var fittedToChunksImage = ImageUtils.FitToBlockSize(rgbImage, CHUNK_SIZE); timer.End(SUB_ID, FITTING); var chunks = fittedToChunksImage.ToBlockArray(CHUNK_SIZE, out int widthBlocks, out int heightBlocks); var dcCoeffs = new List <int>(); var dCTChunks = new DCTChunk[chunks.Length]; //var quantizeCbCrMatrix = MathUtils.BuildQuantizationMatrix(quantCoeffCbCrAC, quantCoeffCbCrDC, BLOCK_SIZE); //MatrixUtils<int>.ShowMatrix(quantizeCbCrMatrix); float[,] quantizeYMatrix = new float[BLOCK_SIZE, BLOCK_SIZE]; /*if (yQuantEnabled) { * quantizeYMatrix = MathUtils.BuildQuantizationMatrix(quantCoeffYAC, quantCoeffYDC, BLOCK_SIZE); * MatrixUtils<int>.ShowMatrix(quantizeYMatrix); * }*/ timer.End(SUB_ID, PREP); timer.Start(SUB_ID, DCT_OF_CHUNK); TransformsUtils.CountCosMatrixFor(BLOCK_SIZE); var parallelOptions = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; var flag = Parallel.ForEach(chunks, parallelOptions, (elem, loopState, elementIndex) => { var dCTChunk = new DCTChunk(new Chunk(chunks[elementIndex], BLOCK_SIZE)); dCTChunk.ZeroCoeffs(percentY, percentCb, percentCr); dCTChunks[elementIndex] = dCTChunk; }); while (!flag.IsCompleted) { ; } timer.End(SUB_ID, DCT_OF_CHUNK); foreach (DCTChunk chunk in dCTChunks) { coeffsCount += chunk.CoeffsCount(); zeroCoeffsCount += chunk.ZeroCoeffsCount(); } var listOfDecompressedImages = new YCbCrImage[dCTChunks.Length]; var listOfDecompressedChunks = new Chunk[dCTChunks.Length]; timer.Start(SUB_ID, REVERSE_DCT); var matrix = new YCbCrImage[widthBlocks, heightBlocks]; flag = Parallel.ForEach(dCTChunks, parallelOptions, (elem, loopState, i) => { listOfDecompressedChunks[i] = new Chunk(dCTChunks[i]); listOfDecompressedImages[i] = YCbCrImage.FromChunk(listOfDecompressedChunks[i]); var j = i / widthBlocks; matrix[i - j * widthBlocks, j] = listOfDecompressedImages[i]; }); while (!flag.IsCompleted) { ; } timer.End(SUB_ID, REVERSE_DCT); var decompressedImage = YCbCrImage.FromMatrix(matrix).ToRGBImage(originalWidth, originalHeight); timer.End(MAIN_ID, FULL_COMPRESS); timer.DisplayIntervals(); return(decompressedImage.ToImage()); }