Exemplo n.º 1
0
        public CompressedImage Compress(Bitmap bmp)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
            {
                throw new Exception($"{bmp.PixelFormat} pixel format is not supported, supported rgb24");
            }
            var pixelsMatrix          = _pixelsExtractor.Extract(bmp);
            var converterPixelsMatrix = MatrixRgbToYCbCrConveter.Convert(pixelsMatrix);
            var residueYPiece         = bmp.Height % (_thinIndex * _dctSize);
            var residueXPiece         = bmp.Width % (_thinIndex * _dctSize);
            var countAddYPiece        = residueYPiece == 0 ? 0 : _thinIndex * _dctSize - residueYPiece;
            var countAddXPiece        = residueXPiece == 0 ? 0 : _thinIndex * _dctSize - residueXPiece;
            var extendedPixelsMatrix  = _matrixExtender.Extend(converterPixelsMatrix, countAddYPiece, countAddXPiece);

            var yCbCrchannels    = _channelExtractor.Extract(extendedPixelsMatrix);
            var thinnedCbChannel = _matrixThinner.Thin(yCbCrchannels.CbChannel, _thinIndex);
            var thinnedCrChannel = _matrixThinner.Thin(yCbCrchannels.CrChannel, _thinIndex);

            var dctYPieces  = _dctCompressor.Compress(yCbCrchannels.YChannel, _dctSize, _compressionLevel, _lumiaMatrixProvider.GetMatrix());
            var dctCbPieces = _dctCompressor.Compress(thinnedCbChannel, _dctSize, _compressionLevel, _colorMatrixProvider.GetMatrix());
            var dctCrPieces = _dctCompressor.Compress(thinnedCrChannel, _dctSize, _compressionLevel, _colorMatrixProvider.GetMatrix());

            var result = new List <byte>();
            var countYBlocksPerColorBlock = _thinIndex * _thinIndex;

            for (int i = 0, thinI = 0; i < dctYPieces.Length; thinI++)
            {
                for (var j = 0; j < countYBlocksPerColorBlock; j++)
                {
                    result.AddRange(dctYPieces[i++]);
                }
                result.AddRange(dctCbPieces[thinI]);
                result.AddRange(dctCrPieces[thinI]);
            }

            var rle = Rle <byte> .Encode(result).ToArray();

            Dictionary <BitsWithLength, byte> decodeTable;
            long bitsCount;
            var  huf = HuffmanCodec.Encode(rle, out decodeTable, out bitsCount);

            var compressedImage = new CompressedImage
            {
                ThinIndex        = _thinIndex,
                CompressionLevel = _compressionLevel,
                DataBytes        = huf,
                Height           = extendedPixelsMatrix.GetLength(0),
                Width            = extendedPixelsMatrix.GetLength(1),
                DecodeTable      = decodeTable,
                BitsCount        = bitsCount
            };

            return(compressedImage);
        }
        public void Test()
        {
            var       bmp1         = (Bitmap)Image.FromFile(@"C:\Users\FessEmpty\Downloads\parallelprogramming-shpora2016-56f562c98bbf\parallelprogramming-shpora2016-56f562c98bbf\JPEG\sample.bmp");
            var       bitmapData1  = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, bmp1.PixelFormat);
            const int rgpPixelSize = 3;
            var       additional   = bitmapData1.Stride - bitmapData1.Width * rgpPixelSize;
            var       result       = new RgbPixel[bmp1.Height, bmp1.Width];

            unsafe
            {
                var imagePointer = (byte *)bitmapData1.Scan0;
                for (var j = 0; j < bitmapData1.Height; j++, imagePointer += additional)
                {
                    for (var i = 0; i < bitmapData1.Width; i++, imagePointer += rgpPixelSize)
                    {
                        result[j, i] = new RgbPixel(imagePointer[0], imagePointer[1], imagePointer[2]);
                    }
                }
            }
            bmp1.UnlockBits(bitmapData1);

            var convert = MatrixRgbToYCbCrConveter.Convert(result);
            var back    = MatrixYCbCrToRgbConverter.Convert(convert);

            var bmp2        = new Bitmap(bmp1.Width, bmp1.Height, bmp1.PixelFormat);
            var bitmapData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, bmp2.PixelFormat);

            unsafe
            {
                var imagePointer = (byte *)bitmapData2.Scan0;
                for (var j = 0; j < bitmapData2.Height; j++, imagePointer += additional)
                {
                    for (var i = 0; i < bitmapData2.Width; i++, imagePointer += rgpPixelSize)
                    {
                        imagePointer[0] = back[j, i].R;
                        imagePointer[1] = back[j, i].G;
                        imagePointer[2] = back[j, i].B;
                    }
                }
            }
            bmp2.UnlockBits(bitmapData2);
            bmp2.Save(@"C:\Users\FessEmpty\Downloads\parallelprogramming-shpora2016-56f562c98bbf\parallelprogramming-shpora2016-56f562c98bbf\JPEG\sampleTest.bmp", ImageFormat.Bmp);
        }