Exemplo n.º 1
0
 /// <summary>
 /// Initializes a new instance of the FastBitmapLocker struct with an initial fast bitmap object.
 /// The fast bitmap object passed will be unlocked after calling Dispose() on this struct
 /// </summary>
 /// <param name="fastBitmap">A fast bitmap to attach to this locker which will be released after a call to Dispose</param>
 public FastBitmapLocker(FastBitmap fastBitmap)
 {
     _fastBitmap = fastBitmap;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Copies a region of the source bitmap into this fast bitmap
        /// </summary>
        /// <param name="source">The source image to copy</param>
        /// <param name="srcRect">The region on the source bitmap that will be copied over</param>
        /// <param name="destRect">The region on this fast bitmap that will be changed</param>
        /// <exception cref="ArgumentException">The provided source bitmap is the same bitmap locked in this FastBitmap</exception>
        public void CopyRegion(Bitmap source, Rectangle srcRect, Rectangle destRect)
        {
            // Throw exception when trying to copy same bitmap over
            if (source == _bitmap)
            {
                throw new ArgumentException("Copying regions across the same bitmap is not supported", "source");
            }

            Rectangle srcBitmapRect  = new Rectangle(0, 0, source.Width, source.Height);
            Rectangle destBitmapRect = new Rectangle(0, 0, _width, _height);

            // Check if the rectangle configuration doesn't generate invalid states or does not affect the target image
            if (srcRect.Width <= 0 || srcRect.Height <= 0 || destRect.Width <= 0 || destRect.Height <= 0 ||
                !srcBitmapRect.IntersectsWith(srcRect) || !destRect.IntersectsWith(destBitmapRect))
            {
                return;
            }

            // Find the areas of the first and second bitmaps that are going to be affected
            srcBitmapRect = Rectangle.Intersect(srcRect, srcBitmapRect);

            // Clip the source rectangle on top of the destination rectangle in a way that clips out the regions of the original bitmap
            // that will not be drawn on the destination bitmap for being out of bounds
            srcBitmapRect = Rectangle.Intersect(srcBitmapRect, new Rectangle(srcRect.X, srcRect.Y, destRect.Width, destRect.Height));

            destBitmapRect = Rectangle.Intersect(destRect, destBitmapRect);

            // Clipt the source bitmap region yet again here
            srcBitmapRect = Rectangle.Intersect(srcBitmapRect, new Rectangle(-destRect.X + srcRect.X, -destRect.Y + srcRect.Y, _width, _height));

            // Calculate the rectangle containing the maximum possible area that is supposed to be affected by the copy region operation
            int copyWidth  = Math.Min((int)srcBitmapRect.Width, (int)destBitmapRect.Width);
            int copyHeight = Math.Min((int)srcBitmapRect.Height, (int)destBitmapRect.Height);

            if (copyWidth == 0 || copyHeight == 0)
            {
                return;
            }

            int srcStartX = srcBitmapRect.Left;
            int srcStartY = srcBitmapRect.Top;

            int destStartX = destBitmapRect.Left;
            int destStartY = destBitmapRect.Top;

            using (FastBitmap fastSource = source.FastLock())
            {
                ulong strideWidth = (ulong)copyWidth * BytesPerPixel;

                for (int y = 0; y < copyHeight; y++)
                {
                    int destX = destStartX;
                    int destY = destStartY + y;

                    int srcX = srcStartX;
                    int srcY = srcStartY + y;

                    long offsetSrc  = (srcX + srcY * fastSource._strideWidth);
                    long offsetDest = (destX + destY * _strideWidth);

                    memcpy((void *)(_scan0 + offsetDest), (void *)(fastSource._scan0 + offsetSrc), strideWidth);
                }
            }
        }