Beispiel #1
0
        /// <summary>
        /// Build a bitmap with any of the given score bits set
        /// </summary>
        Frame BuildBitmap(Bitmap32Bits frame,
                          List <Block> blocks,
                          Dictionary <int, int> duplicates,
                          Score score,
                          ImageFormat format)
        {
            // Count blocks to write to target
            int numTargetBlocks = 0;

            foreach (var block in blocks)
            {
                if ((block.Score & score & (Score.Jpg | Score.Png)) != Score.None)
                {
                    numTargetBlocks++;
                }
            }

            // Generate the bitmap
            int size        = (int)Math.Sqrt(numTargetBlocks) + 1;
            var bmTarget    = new Bitmap(size * mBlockSize, size * mBlockSize, PixelFormat.Format32bppArgb);
            var bmdTarget   = new Bitmap32Bits(bmTarget, ImageLockMode.WriteOnly);
            var blockWriter = new BlockWriter(frame, bmdTarget, mBlockSize, duplicates);

            foreach (var block in blocks)
            {
                if ((block.Score & score) != Score.None)
                {
                    blockWriter.Write(block);
                }
            }
            bmdTarget.Dispose();

            // Compress frame to stream
            var targetStream = new MemoryStream();

            bmTarget.Save(targetStream, format);
            bmTarget.Dispose();
            return(new Frame(blockWriter.GetDrawString(), targetStream, format));
        }
Beispiel #2
0
        /// <summary>
        /// Analyze a bitmap, and keep a copy as the new background.  If the bitmap is not
        /// the same size as the previous one, a new comparison is made.  You must
        /// dispose the bitmap when done with it.  Returns 1 or 2 frames (PNG/JPG)
        /// depending on settings
        /// </summary>
        public Frame [] Compress(Bitmap frame)
        {
            // Generate full frame JPG or PNG (debugging output)
            if (mOutput == OutputType.FullFrameJpg || mOutput == OutputType.FullFramePng)
            {
                var f = GenerateFullFrame((Bitmap)frame, mOutput == OutputType.FullFrameJpg ? ImageFormat.Jpeg : ImageFormat.Png);
                return(new Frame[] { f });
            }

            // Force full frame analysis if requested
            bool disableDelta = mForceDisableDelta ||
                                mFullFrameAnalysis ||
                                Output == OutputType.HideJpg ||
                                Output == OutputType.HidePng;

            mForceDisableDelta = false;

            // Optionally create background if it doesn't exist, or the size changed
            if (mBackground == null || mBackground.Width != frame.Width || mBackground.Height != frame.Height)
            {
                // New background, do not compare with previous
                disableDelta = true;
                if (mBackground != null)
                {
                    mBackground.Dispose();
                }
                mBackground = new Bitmap32Bits(frame.Width, frame.Height);
            }

            // Number of blocks visible (even if partially visible)
            mBlocksX = (frame.Width + mBlockSize - 1) / mBlockSize;

            // Score bitmap
            mFrameIndex++;
            var                   frameBits = new Bitmap32Bits(frame, ImageLockMode.ReadOnly);
            List <Block>          blocks;
            Dictionary <int, int> duplicates;
            int                   jpgCount;
            int                   pngCount;

            ScoreFrame(frameBits, disableDelta, out blocks, out duplicates, out jpgCount, out pngCount);

            // Build the bitmaps (JPG and PNG)
            Frame[] frames;
            if (jpgCount == 0 || pngCount == 0)
            {
                // Build one frame (both PNG and JPG)
                frames = new Frame[]
                { BuildBitmap(frameBits, blocks,
                              duplicates, Score.Solid | Score.Duplicate | Score.Jpg | Score.Png,
                              pngCount == 0 ? ImageFormat.Jpeg : ImageFormat.Png) };
            }
            else
            {
                // Build two frames (PNG first, and JPG second)
                frames = new Frame[]
                { BuildBitmap(frameBits, blocks, duplicates, Score.Solid | Score.Duplicate | Score.Png, ImageFormat.Png),
                  BuildBitmap(frameBits, blocks, duplicates, Score.Duplicate | Score.Jpg, ImageFormat.Jpeg) };
            }
            frameBits.Dispose();

            // Optionally create compression maps and other debug output
            if (mOutput == OutputType.CompressionMap)
            {
                CopyDuplicateAttributesForDebug(blocks, duplicates);
                var map = GenerateCompressionMap(frame.Width, frame.Height, blocks);
                var f   = GenerateFullFrame(map, ImageFormat.Png);
                map.Dispose();
                return(new Frame[] { f });
            }
            else if (mOutput == OutputType.HideJpg || mOutput == OutputType.HidePng)
            {
                CopyDuplicateAttributesForDebug(blocks, duplicates);
                var map = GenerateHideMap(frame, blocks, mOutput == OutputType.HideJpg ? Score.Jpg : Score.Png);
                var f   = GenerateFullFrame(map, ImageFormat.Jpeg);
                map.Dispose();
                return(new Frame[] { f });
            }
            return(frames);
        }