Inheritance: IDisposable
Example #1
1
        public void Apply(FastBitmap surface, Rectangle[] roi, int startIndex, int length)
        {
            Rectangle regionBounds = Utility.GetRegionBounds (roi, startIndex, length);

            if (regionBounds != Rectangle.Intersect (surface.GetBounds (), regionBounds))
                throw new ArgumentOutOfRangeException ("roi", "Region is out of bounds");

            unsafe {
                for (int x = startIndex; x < startIndex + length; ++x)
                    ApplyRectangle (surface, roi[x]);
            }
        }
        /// <summary>
        /// Returns the color count from the palette of the given image.
        /// </summary>
        /// <param name="image">
        /// The <see cref="System.Drawing.Image"/> to get the colors from.
        /// </param>
        /// <returns>
        /// The <see cref="int"/> representing the color count.
        /// </returns>
        public static int GetColorCount(Image image)
        {
            ConcurrentDictionary<Color, Color> colors = new ConcurrentDictionary<Color, Color>();
            int width = image.Width;
            int height = image.Height;

            using (FastBitmap fastBitmap = new FastBitmap(image))
            {
                Parallel.For(
                    0,
                    height,
                    y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            Color color = fastBitmap.GetPixel(x, y);
                            colors.TryAdd(color, color);
                        }
                    });
            }

            int count = colors.Count;
            colors.Clear();
            return count;
        }
        public static int CountColors(this Image image)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }

            HashSet<int> colors = new HashSet<int>();

            FastBitmap fastBitmap = new FastBitmap(image);
            fastBitmap.Lock();

            // Loop through all the pixels of the image
            // and add the colors to the HashSet - duplicates
            // are automatically ignored by that collection type
            for (int x = 0; x < image.Width; x++)
            {
                for (int y = 0; y < image.Height; y++)
                {
                    // We use ToArgb because Colors are compared on more than their ARGB values - see Color class documentation on MSDN
                    colors.Add(fastBitmap.GetPixel(x, y).ToArgb());
                }
            }

            fastBitmap.Unlock();

            return colors.Count;
        }
        /// <summary>
        /// Processes the given bitmap to apply the threshold.
        /// </summary>
        /// <param name="source">
        /// The image to process.
        /// </param>
        /// <returns>
        /// A processed bitmap.
        /// </returns>
        public Bitmap ProcessFilter(Bitmap source)
        {
            int width = source.Width;
            int height = source.Height;

            using (FastBitmap sourceBitmap = new FastBitmap(source))
            {
                Parallel.For(
                    0, 
                    height, 
                    y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // ReSharper disable AccessToDisposedClosure
                            Color color = sourceBitmap.GetPixel(x, y);
                            sourceBitmap.SetPixel(x, y, color.B >= this.threshold ? Color.White : Color.Black);

                            // ReSharper restore AccessToDisposedClosure
                        }
                    });
            }

            return source;
        }
Example #5
0
        public void TestFastBitmapCreation()
        {
            Bitmap bitmap = new Bitmap(64, 64);
            FastBitmap fastBitmap = new FastBitmap(bitmap);
            fastBitmap.Lock();
            fastBitmap.Unlock();

            // Try creating a FastBitmap with different 32bpp depths
            try
            {
                // ReSharper disable once ObjectCreationAsStatement
                new FastBitmap(new Bitmap(1, 1, PixelFormat.Format32bppArgb));
                // ReSharper disable once ObjectCreationAsStatement
                new FastBitmap(new Bitmap(1, 1, PixelFormat.Format32bppPArgb));
                // ReSharper disable once ObjectCreationAsStatement
                new FastBitmap(new Bitmap(1, 1, PixelFormat.Format32bppRgb));
            }
            catch (ArgumentException)
            {
                Assert.Fail("The FastBitmap should accept any type of 32bpp pixel format bitmap");
            }

            // Try creating a FastBitmap with a bitmap of a bit depth different from 32bpp
            Bitmap invalidBitmap = new Bitmap(64, 64, PixelFormat.Format4bppIndexed);

            // ReSharper disable once ObjectCreationAsStatement
            new FastBitmap(invalidBitmap);
        }
Example #6
0
        /// <summary>
        /// Adjusts the alpha component of the given image.
        /// </summary>
        /// <param name="source">
        /// The <see cref="Image"/> source to adjust.
        /// </param>
        /// <param name="percentage">
        /// The percentage value between 0 and 100 for adjusting the opacity.
        /// </param>
        /// <param name="rectangle">The rectangle to define the bounds of the area to adjust the opacity. 
        /// If null then the effect is applied to the entire image.</param>
        /// <returns>
        /// The <see cref="Bitmap"/> with the alpha component adjusted.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown if the percentage value falls outside the acceptable range.
        /// </exception>
        public static Bitmap Alpha(Image source, int percentage, Rectangle? rectangle = null)
        {
            if (percentage > 100 || percentage < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(percentage), "Percentage should be between 0 and 100.");
            }

            float factor = (float)percentage / 100;
            int width = source.Width;
            int height = source.Height;

            // Traditional examples using a color matrix alter the rgb values also.
            using (FastBitmap bitmap = new FastBitmap(source))
            {
                // Loop through the pixels.
                Parallel.For(
                    0,
                    height,
                    y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // ReSharper disable AccessToDisposedClosure
                            Color color = bitmap.GetPixel(x, y);
                            bitmap.SetPixel(x, y, Color.FromArgb(Convert.ToInt32(color.A * factor), color.R, color.G, color.B));
                            // ReSharper restore AccessToDisposedClosure
                        }
                    });
            }

            return (Bitmap)source;
        }
        /// <summary> Disposes the atlas bitmap that contains animation frames, and clears
        /// the list of defined animations. </summary>
        public void Dispose()
        {
            animations.Clear();

            if( bmp == null ) return;
            fastBmp.Dispose(); fastBmp = null;
            bmp.Dispose(); bmp = null;
        }
Example #8
0
        /// <summary>
        /// Applies the given image mask to the source.
        /// </summary>
        /// <param name="source">
        /// The source <see cref="Image"/>.
        /// </param>
        /// <param name="mask">
        /// The mask <see cref="Image"/>.
        /// </param>
        /// <exception cref="ArgumentException">
        /// Thrown if the two images are of different size.
        /// </exception>
        /// <returns>
        /// The masked <see cref="Bitmap"/>.
        /// </returns>
        public static Bitmap ApplyMask(Image source, Image mask)
        {
            if (mask.Size != source.Size)
            {
                throw new ArgumentException();
            }

            int width = mask.Width;
            int height = mask.Height;

            Bitmap toMask = new Bitmap(source);
            toMask.SetResolution(source.HorizontalResolution, source.VerticalResolution);

            // Loop through and replace the alpha channel
            using (FastBitmap maskBitmap = new FastBitmap(mask))
            {
                using (FastBitmap sourceBitmap = new FastBitmap(toMask))
                {
                    Parallel.For(
                        0,
                        height,
                        y =>
                        {
                            for (int x = 0; x < width; x++)
                            {
                                // ReSharper disable AccessToDisposedClosure
                                Color maskColor = maskBitmap.GetPixel(x, y);
                                Color sourceColor = sourceBitmap.GetPixel(x, y);

                                if (sourceColor.A != 0)
                                {
                                    sourceBitmap.SetPixel(x, y, Color.FromArgb(maskColor.A, sourceColor.R, sourceColor.G, sourceColor.B));
                                }

                                // ReSharper restore AccessToDisposedClosure
                            }
                        });
                }
            }

            // Ensure the background is cleared out on non alpha supporting formats.
            Bitmap clear = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
            clear.SetResolution(source.HorizontalResolution, source.VerticalResolution);
            using (Graphics graphics = Graphics.FromImage(clear))
            {
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.Clear(Color.Transparent);

                graphics.DrawImageUnscaled(toMask, 0, 0, width, height);
            }

            toMask.Dispose();
            return clear;
        }
Example #9
0
        /// <summary> Disposes the atlas bitmap that contains animation frames, and clears
        /// the list of defined animations. </summary>
        public void Clear()
        {
            animations.Clear();

            if( animBmp == null ) return;
            animsBuffer.Dispose(); animsBuffer = null;
            animBmp.Dispose(); animBmp = null;
            validated = false;
        }
Example #10
0
        protected unsafe virtual void RenderEffect(FastBitmap src, FastBitmap dst, Rectangle roi)
        {
            PixelData* src_data_ptr = (PixelData*)src.DataPtr;
            int src_width = src.Width;
            PixelData* dst_data_ptr = (PixelData*)dst.DataPtr;
            int dst_width = dst.Width;

            for (int y = roi.Y; y < roi.Bottom; ++y) {
                PixelData* srcPtr = src.GetPointAddressUnchecked (src_data_ptr, src_width, roi.X, y);
                PixelData* dstPtr = dst.GetPointAddressUnchecked (dst_data_ptr, dst_width, roi.X, y);
                RenderLine (srcPtr, dstPtr, roi.Width);
            }
        }
Example #11
0
        /// <summary>
        /// Provides a default implementation for performing dst = F(dst, src) or F(src) over some rectangle 
        /// of interest. May be slightly faster than calling the other multi-parameter Apply method, as less 
        /// variables are used in the implementation, thus inducing less register pressure.
        /// </summary>
        /// <param name="dst">The Surface to write pixels to, and from which pixels are read and used as the lhs parameter for calling the method <b>PixelData Apply(PixelData, PixelData)</b>.</param>
        /// <param name="dstOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the dst Surface.</param>
        /// <param name="src">The Surface to read pixels from for the rhs parameter given to the method <b>PixelData Apply(PixelData, PixelData)</b>b>.</param></param>
        /// <param name="srcOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the src Surface.</param>
        /// <param name="roiSize">The size of the rectangles-of-interest for all Surfaces.</param>
        public void ApplyBase(FastBitmap dst, Point dstOffset, FastBitmap src, Point srcOffset, Size roiSize)
        {
            // Create bounding rectangles for each Surface
            Rectangle dstRect = new Rectangle (dstOffset, roiSize);

            if (dstRect.Width == 0 || dstRect.Height == 0)
                return;

            Rectangle srcRect = new Rectangle (srcOffset, roiSize);

            if (srcRect.Width == 0 || srcRect.Height == 0)
                return;

            // Clip those rectangles to those Surface's bounding rectangles
            Rectangle dstClip = Rectangle.Intersect (dstRect, dst.GetBounds ());
            Rectangle srcClip = Rectangle.Intersect (srcRect, src.GetBounds ());

            // If any of those Rectangles actually got clipped, then throw an exception
            if (dstRect != dstClip)
                throw new ArgumentOutOfRangeException
                (
                    "roiSize",
                    "Destination roi out of bounds" +
                    string.Format (", dst.Size=({0},{1}", dst.Width, dst.Height) +
                    ", dst.Bounds=" + dst.GetBounds ().ToString () +
                    ", dstOffset=" + dstOffset.ToString () +
                    string.Format (", src.Size=({0},{1}", src.Width, src.Height) +
                    ", srcOffset=" + srcOffset.ToString () +
                    ", roiSize=" + roiSize.ToString () +
                    ", dstRect=" + dstRect.ToString () +
                    ", dstClip=" + dstClip.ToString () +
                    ", srcRect=" + srcRect.ToString () +
                    ", srcClip=" + srcClip.ToString ()
                );

            if (srcRect != srcClip)
                throw new ArgumentOutOfRangeException ("roiSize", "Source roi out of bounds");

            // Cache the width and height properties
            int width = roiSize.Width;
            int height = roiSize.Height;

            // Do the work.
            unsafe {
                for (int row = 0; row < roiSize.Height; ++row) {
                    PixelData* dstPtr = dst.GetPointAddress (dstOffset.X, dstOffset.Y + row);
                    PixelData* srcPtr = src.GetPointAddress (srcOffset.X, srcOffset.Y + row);
                    Apply (dstPtr, srcPtr, width);
                }
            }
        }
        //tiles = 16 means 16 x 16 atlas
        public List<Bitmap> Atlas2dInto1d(Bitmap atlas2d, int tiles, int atlassizezlimit)
        {
            FastBitmap orig = new FastBitmap();
            orig.bmp = atlas2d;

            int tilesize = atlas2d.Width / tiles;

            int atlasescount = Math.Max(1, (tiles * tiles * tilesize) / atlassizezlimit);
            List<Bitmap> atlases = new List<Bitmap>();

            orig.Lock();

            //256 x 1
            FastBitmap atlas1d = null;

            for (int i = 0; i < tiles * tiles; i++)
            {
                int x = i % tiles;
                int y = i / tiles;
                int tilesinatlas = (tiles * tiles / atlasescount);
                if (i % tilesinatlas == 0)
                {
                    if (atlas1d != null)
                    {
                        atlas1d.Unlock();
                        atlases.Add(atlas1d.bmp);
                    }
                    atlas1d = new FastBitmap();
                    atlas1d.bmp = new Bitmap(tilesize, atlassizezlimit);
                    atlas1d.Lock();
                }
                for (int xx = 0; xx < tilesize; xx++)
                {
                    for (int yy = 0; yy < tilesize; yy++)
                    {
                        int c = orig.GetPixel(x * tilesize + xx, y * tilesize + yy);
                        atlas1d.SetPixel(xx, (i % tilesinatlas) * tilesize + yy, c);
                    }
                }
            }
            atlas1d.Unlock();
            atlases.Add(atlas1d.bmp);
            orig.Unlock();
            return atlases;
        }
Example #13
0
        public Bitmap DrawImage(Color[] colors)
        {
            if (Width < 1 || Height < 1) {
                return null;
            }

            var image = new Bitmap(Width, Height);
            var fastBmp = new FastBitmap(image);

            fastBmp.LockImage();
            for (int y = 0, i = 0; y < Height; y++) {
                for (var x = 0; x < Width; x++) {
                    fastBmp.SetPixel(x, y, colors[(int)Cells[i++].Type]);
                }
            }
            fastBmp.UnlockImage();

            return image;
        }
Example #14
0
        public void TestSequentialFastBitmapLocking()
        {
            Bitmap bitmap = new Bitmap(64, 64);
            FastBitmap fastBitmap = new FastBitmap(bitmap);

            Assert.IsFalse(fastBitmap.Locked, "Immediately after creation, the FastBitmap.Locked property must be false");

            fastBitmap.Lock();

            Assert.IsTrue(fastBitmap.Locked, "After a successful call to .Lock(), the .Locked property must be true");

            fastBitmap.Unlock();

            Assert.IsFalse(fastBitmap.Locked, "After a successful call to .Lock(), the .Locked property must be false");

            fastBitmap = new FastBitmap(bitmap);
            fastBitmap.Lock();
            fastBitmap.Unlock();
        }
Example #15
0
		public Bitmap DrawImage(Color[] Colors) {
			if (Width < 1 || Height < 1) {
				return null;
			}

			Bitmap Image = new Bitmap(Width, Height);
			FastBitmap fastBmp = new FastBitmap(Image);

			using (Graphics g = Graphics.FromImage(Image)) {

				fastBmp.LockImage();
				for (int y = 0, i = 0; y < Height; y++) {
					for (int x = 0; x < Width; x++) {
						fastBmp.SetPixel(x, y, Colors[(int)Cells[i++].Type]);
					}
				}
				fastBmp.UnlockImage();
			}

			return Image;
		}
        public static bool CompareColors(this Image image, Image other)
        {
            if (image == null || other == null)
            {
                throw new ArgumentNullException(image == null ? "image" : "other");
            }

            if (image.Size != other.Size)
            {
                return false;
            }

            FastBitmap fastImage = new FastBitmap(image);
            FastBitmap fastOther = new FastBitmap(other);

            try
            {
                fastImage.Lock();
                fastOther.Lock();

                for (int x = 0; x < image.Width; x++)
                {
                    for (int y = 0; y < image.Height; y++)
                    {
                        // We use ToArgb because Colors are compared on more than their ARGB values - see Color class documentation on MSDN
                        if (fastImage.GetPixel(x, y).ToArgb() != fastOther.GetPixel(x, y).ToArgb())
                        {
                            return false;
                        }
                    }
                }
            }
            finally
            {
                fastImage.Unlock();
                fastOther.Unlock();
            }

            return true;
        }
Example #17
0
        public static void GenerateBitmap(byte[] data, FastBitmap bmp, int startY, int dataAddress, List<Color> fourColors, int addY)
        {
            int index = 0;
            bool onlyHalf = false;
            int y = startY;
            int x = 0;
            int colorZeroValue = fourColors[0].ToArgb();
            while (y < bmp.Height && dataAddress + index + 2 < data.Length)
            {
                int runLength;
                int color;
                bool restOfLine;
                index += DecodeRle(dataAddress + index, data, out color, out runLength, ref onlyHalf, out restOfLine);
                if (restOfLine)
                    runLength = bmp.Width - x;

                Color c = fourColors[color]; // set color via the four colors
                for (int i = 0; i < runLength; i++, x++)
                {
                    if (x >= bmp.Width-1)
                    {
                        if (y < bmp.Height && x < bmp.Width && c != fourColors[0])
                            bmp.SetPixel(x, y, c);

                        if (onlyHalf)
                        {
                            onlyHalf = false;
                            index++;
                        }
                        x = 0;
                        y += addY;
                        break;
                    }
                    if (y < bmp.Height && c.ToArgb() != colorZeroValue)
                       bmp.SetPixel(x, y, c);
                }
            }
        }
            /// <summary>
            /// Decode caption from the input stream
            /// </summary>
            /// <returns>bitmap of the decoded caption</returns>
            public static Bitmap DecodeImage(PcsObject pcs, IList<OdsData> data, List<PaletteInfo> palettes)
            {
                if (pcs == null || data == null || data.Count == 0)
                    return new Bitmap(1, 1);

                int w = data[0].Size.Width;
                int h = data[0].Size.Height;

                var bm = new FastBitmap(new Bitmap(w, h));
                bm.LockImage();
                BluRaySupPalette pal = DecodePalette(palettes);

                int index = 0;
                int ofs = 0;
                int xpos = 0;

                byte[] buf = data[0].Fragment.ImageBuffer;
                index = 0;
                do
                {
                    int b = buf[index++] & 0xff;
                    if (b == 0 && index < buf.Length)
                    {
                        b = buf[index++] & 0xff;
                        if (b == 0)
                        {
                            // next line
                            ofs = (ofs / w) * w;
                            if (xpos < w)
                                ofs += w;
                            xpos = 0;
                        }
                        else
                        {
                            int size;
                            if ((b & 0xC0) == 0x40)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 4x xx -> xxx zeroes
                                    size = ((b - 0x40) << 8) + (buf[index++] & 0xff);
                                    Color c = Color.FromArgb(pal.GetArgb(0));
                                    for (int i = 0; i < size; i++)
                                        PutPixel(bm, ofs++, c);
                                    xpos += size;
                                }
                            }
                            else if ((b & 0xC0) == 0x80)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 8x yy -> x times value y
                                    size = (b - 0x80);
                                    b = buf[index++] & 0xff;
                                    Color c = Color.FromArgb(pal.GetArgb(b));
                                    for (int i = 0; i < size; i++)
                                        PutPixel(bm, ofs++, c);
                                    xpos += size;
                                }
                            }
                            else if ((b & 0xC0) != 0)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 cx yy zz -> xyy times value z
                                    size = ((b - 0xC0) << 8) + (buf[index++] & 0xff);
                                    b = buf[index++] & 0xff;
                                    Color c = Color.FromArgb(pal.GetArgb(b));
                                    for (int i = 0; i < size; i++)
                                        PutPixel(bm, ofs++, c);
                                    xpos += size;
                                }
                            }
                            else
                            {
                                // 00 xx -> xx times 0
                                Color c = Color.FromArgb(pal.GetArgb(0));
                                for (int i = 0; i < b; i++)
                                    PutPixel(bm, ofs++, c);
                                xpos += b;
                            }
                        }
                    }
                    else
                    {
                        PutPixel(bm, ofs++, b, pal);
                        xpos++;
                    }
                } while (index < buf.Length);

                bm.UnlockImage();
                return bm.GetBitmap();
            }
Example #19
0
 public void SetAtlas( Bitmap bmp )
 {
     Dispose();
     this.bmp = bmp;
     fastBmp = new FastBitmap( bmp, true );
 }
Example #20
0
        unsafe void ApplyAnimation( AnimationData data )
        {
            data.Tick--;
            if( data.Tick >= 0 ) return;
            data.CurrentState++;
            data.CurrentState %= data.StatesCount;
            data.Tick = data.TickDelay;

            TerrainAtlas1D atlas = game.TerrainAtlas1D;
            int texId = ( data.TileY << 4 ) | data.TileX;
            int index = atlas.Get1DIndex( texId );
            int rowNum = atlas.Get1DRowId( texId );

            int size = data.FrameSize;
            byte* temp = stackalloc byte[size * size * 4];
            FastBitmap part = new FastBitmap( size, size, size * 4, (IntPtr)temp );
            FastBitmap.MovePortion( data.FrameX + data.CurrentState * size, data.FrameY, 0, 0, fastBmp, part, size );
            api.UpdateTexturePart( atlas.TexIds[index], 0, rowNum * game.TerrainAtlas.elementSize, part );
        }
        /// <summary>
        ///   Performs object detection on the given frame.
        /// </summary>
        /// 
        //public Rectangle[] ProcessFrame(Bitmap frame)
        //{
        //    using (FastBitmap fastBitmap = new FastBitmap(frame))
        //    {
        //        return ProcessFrame(fastBitmap);
        //    }
        //}

        /// <summary>
        ///   Performs object detection on the given frame.
        /// </summary>
        /// 
        public Rectangle[] ProcessFrame(Bitmap image)
        {
          //  int colorChannel =
           //   image.PixelFormat == PixelFormat.Format8bppIndexed ? 0 : channel;

            Rectangle[] objects;

            // Creates an integral image representation of the frame
            using (FastBitmap fastBitmap = new FastBitmap(image, this.classifier.Cascade.HasTiltedFeatures))
            {
                // Creates a new list of detected objects.
                this.detectedObjects.Clear();

                int width = fastBitmap.Width;
                int height = fastBitmap.Height;

                // Update parameters only if different size
                if (steps == null || width != lastWidth || height != lastHeight)
                    update(width, height);


                Rectangle window = Rectangle.Empty;

                // For each scaling step
                for (int i = 0; i < steps.Length; i++)
                {
                    float scaling = steps[i];

                    // Set the classifier window scale
                    classifier.Scale = scaling;

                    // Get the scaled window size
                    window.Width = (int)(baseWidth * scaling);
                    window.Height = (int)(baseHeight * scaling);

                    // Check if the window is lesser than the minimum size
                    if (window.Width < minSize.Width || window.Height < minSize.Height)
                    {
                        // If we are searching in greater to smaller mode,
                        if (scalingMode == ObjectDetectorScalingMode.GreaterToSmaller)
                        {
                            break; // it won't get bigger, so we should stop.
                        }
                        else continue; // continue until it gets greater.
                    }

                    // Check if the window is greater than the maximum size
                    else if (window.Width > maxSize.Width || window.Height > maxSize.Height)
                    {
                        // If we are searching in greater to smaller mode,
                        if (scalingMode == ObjectDetectorScalingMode.GreaterToSmaller)
                        {
                            continue; // continue until it gets smaller.
                        }

                        break; // it won't get smaller, so we should stop. 
                    }

                    // Grab some scan loop parameters
                    int xStep = window.Width >> 3;
                    int yStep = window.Height >> 3;

                    int xEnd = width - window.Width;
                    int yEnd = height - window.Height;


                    // Parallel mode. Scan the integral image searching
                    // for objects in the window with parallelization.
                    var bag = new System.Collections.Concurrent.ConcurrentBag<Rectangle>();

                    int numSteps = (int)Math.Ceiling((double)yEnd / yStep);

                    // For each pixel in the window column
                    var window1 = window;
                    Parallel.For(
                        0,
                        numSteps,
                        (j, options) =>
                        {
                            int y = j * yStep;

                            // Create a local window reference
                            Rectangle localWindow = window1;

                            localWindow.Y = y;

                            // For each pixel in the window row
                            for (int x = 0; x < xEnd; x += xStep)
                            {
                                if (options.ShouldExitCurrentIteration) return;

                                localWindow.X = x;

                                // Try to detect and object inside the window
                                if (classifier.Compute(fastBitmap, localWindow))
                                {
                                    // an object has been detected
                                    bag.Add(localWindow);

                                    if (searchMode == ObjectDetectorSearchMode.Single)
                                        options.Stop();
                                }
                            }
                        });

                    // If required, avoid adding overlapping objects at
                    // the expense of extra computation. Otherwise, only
                    // add objects to the detected objects collection.
                    if (searchMode == ObjectDetectorSearchMode.NoOverlap)
                    {
                        foreach (Rectangle obj in bag)
                        {
                            if (!overlaps(obj))
                            {
                                detectedObjects.Add(obj);
                            }
                        }
                    }
                    else if (searchMode == ObjectDetectorSearchMode.Single)
                    {
                        if (bag.TryPeek(out window))
                        {
                            detectedObjects.Add(window);
                            break;
                        }
                    }
                    else
                    {
                        foreach (Rectangle obj in bag)
                        {
                            detectedObjects.Add(obj);
                        }
                    }
                }
            }

            objects = detectedObjects.ToArray();

            if (searchMode == ObjectDetectorSearchMode.Average)
            {
                objects = match.Group(objects);
            }

            checkSteadiness(objects);
            lastObjects = objects;

            return objects; // Returns the array of detected objects.
        }
Example #22
0
        /// <summary>
        /// Traces the edges of a given <see cref="Image"/>.
        /// </summary>
        /// <param name="source">
        /// The source <see cref="Image"/>.
        /// </param>
        /// <param name="destination">
        /// The destination <see cref="Image"/>.
        /// </param>
        /// <param name="threshold">
        /// The threshold (between 0 and 255).
        /// </param>
        /// <returns>
        /// The a new instance of <see cref="Bitmap"/> traced.
        /// </returns>
        public static Bitmap Trace(Image source, Image destination, byte threshold = 0)
        {
            int width = source.Width;
            int height = source.Height;

            // Grab the edges converting to greyscale, and invert the colors.
            ConvolutionFilter filter = new ConvolutionFilter(new SobelEdgeFilter(), true);

            using (Bitmap temp = filter.Process2DFilter(source))
            {
                destination = new InvertMatrixFilter().TransformImage(temp, destination);

                // Darken it slightly to aid detection
                destination = Adjustments.Brightness(destination, -5);
            }

            // Loop through and replace any colors more white than the threshold
            // with a transparent one.
            using (FastBitmap destinationBitmap = new FastBitmap(destination))
            {
                Parallel.For(
                    0,
                    height,
                    y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // ReSharper disable AccessToDisposedClosure
                            Color color = destinationBitmap.GetPixel(x, y);
                            if (color.B >= threshold)
                            {
                                destinationBitmap.SetPixel(x, y, Color.Transparent);
                            }
                            // ReSharper restore AccessToDisposedClosure
                        }
                    });
            }

            // Darken it again to average out the color.
            destination = Adjustments.Brightness(destination, -5);

            return (Bitmap)destination;
        }
 /// <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;
 }
        /// <summary>
        /// Applies the oil painting filter. 
        /// </summary>
        /// <param name="source">
        /// The source.
        /// </param>
        /// <returns>
        /// The <see cref="Bitmap"/>.
        /// </returns>
        public Bitmap ApplyFilter(Bitmap source)
        {
            // TODO: Make this class implement an interface?
            int width = source.Width;
            int height = source.Height;

            int radius = this.brushSize >> 1;

            Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
            destination.SetResolution(source.HorizontalResolution, source.VerticalResolution);
            using (FastBitmap sourceBitmap = new FastBitmap(source))
            {
                using (FastBitmap destinationBitmap = new FastBitmap(destination))
                {
                    Parallel.For(
                        0,
                        height,
                        y =>
                        {
                            for (int x = 0; x < width; x++)
                            {
                                int maxIntensity = 0;
                                int maxIndex = 0;
                                int[] intensityBin = new int[this.levels];
                                int[] blueBin = new int[this.levels];
                                int[] greenBin = new int[this.levels];
                                int[] redBin = new int[this.levels];
                                byte sourceAlpha = 255;

                                for (int i = 0; i <= radius; i++)
                                {
                                    int ir = i - radius;
                                    int offsetY = y + ir;

                                    // Skip the current row
                                    if (offsetY < 0)
                                    {
                                        continue;
                                    }

                                    // Outwith the current bounds so break.
                                    if (offsetY >= height)
                                    {
                                        break;
                                    }

                                    for (int fx = 0; fx <= radius; fx++)
                                    {
                                        int jr = fx - radius;
                                        int offsetX = x + jr;

                                        // Skip the column
                                        if (offsetX < 0)
                                        {
                                            continue;
                                        }

                                        if (offsetX < width)
                                        {
                                            // ReSharper disable once AccessToDisposedClosure
                                            Color color = sourceBitmap.GetPixel(offsetX, offsetY);

                                            byte sourceBlue = color.B;
                                            byte sourceGreen = color.G;
                                            byte sourceRed = color.R;
                                            sourceAlpha = color.A;

                                            int currentIntensity = (int)Math.Round(((sourceBlue + sourceGreen + sourceRed) / 3.0 * (this.levels - 1)) / 255.0);

                                            intensityBin[currentIntensity] += 1;
                                            blueBin[currentIntensity] += sourceBlue;
                                            greenBin[currentIntensity] += sourceGreen;
                                            redBin[currentIntensity] += sourceRed;

                                            if (intensityBin[currentIntensity] > maxIntensity)
                                            {
                                                maxIntensity = intensityBin[currentIntensity];
                                                maxIndex = currentIntensity;
                                            }
                                        }
                                    }
                                }

                                byte blue = Math.Abs(blueBin[maxIndex] / maxIntensity).ToByte();
                                byte green = Math.Abs(greenBin[maxIndex] / maxIntensity).ToByte();
                                byte red = Math.Abs(redBin[maxIndex] / maxIntensity).ToByte();

                                // ReSharper disable once AccessToDisposedClosure
                                destinationBitmap.SetPixel(x, y, Color.FromArgb(sourceAlpha, red, green, blue));
                            }
                        });
                }
            }

            return destination;
        }
 private static void PutPixel(FastBitmap bmp, int index, int color, BluRaySupPalette palette)
 {
     int x = index % bmp.Width;
     int y = index / bmp.Width;
     if (x < bmp.Width && y < bmp.Height)
         bmp.SetPixel(x, y, Color.FromArgb(palette.GetArgb(color)));
 }
Example #26
0
        /// <summary>
        /// Converts an image from a linear color-space to the equivalent sRGB color-space.
        /// </summary>
        /// <param name="source">
        /// The <see cref="Image"/> source to convert.
        /// </param>
        /// <returns>
        /// The <see cref="Bitmap"/>.
        /// </returns>
        public static Bitmap ToSRGB(Image source)
        {
            // Create only once and lazily.
            byte[] ramp = SRGBBytes.Value;

            int width = source.Width;
            int height = source.Height;

            using (FastBitmap bitmap = new FastBitmap(source))
            {
                Parallel.For(
                    0,
                    height,
                    y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            Color composite = bitmap.GetPixel(x, y);
                            Color linear = Color.FromArgb(composite.A, ramp[composite.R], ramp[composite.G], ramp[composite.B]);
                            // ReSharper disable once AccessToDisposedClosure
                            bitmap.SetPixel(x, y, linear);
                        }
                    });
            }

            return (Bitmap)source;
        }
Example #27
0
        /// <summary>
        /// Adjust the gamma (intensity of the light) component of the given image.
        /// </summary>
        /// <param name="source">
        /// The <see cref="Image"/> source to adjust.
        /// </param>
        /// <param name="value">
        /// The value to adjust the gamma by (typically between .2 and 5).
        /// </param>
        /// <returns>
        /// The <see cref="Bitmap"/> with the gamma adjusted.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown if the value falls outside the acceptable range.
        /// </exception>
        public static Bitmap Gamma(Image source, float value)
        {
            if (value > 5 || value < .1)
            {
                throw new ArgumentOutOfRangeException(nameof(value), "Value should be between .1 and 5.");
            }

            byte[] ramp = new byte[256];
            for (int x = 0; x < 256; ++x)
            {
                byte val = ((255.0 * Math.Pow(x / 255.0, value)) + 0.5).ToByte();
                ramp[x] = val;
            }

            int width = source.Width;
            int height = source.Height;

            using (FastBitmap bitmap = new FastBitmap(source))
            {
                Parallel.For(
                    0,
                    height,
                    y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            Color composite = bitmap.GetPixel(x, y);
                            Color linear = Color.FromArgb(composite.A, ramp[composite.R], ramp[composite.G], ramp[composite.B]);
                            // ReSharper disable once AccessToDisposedClosure
                            bitmap.SetPixel(x, y, linear);
                        }
                    });
            }

            return (Bitmap)source;
        }
        /// <summary>
        /// Processes the given bitmap to apply the current instance of <see cref="IEdgeFilter"/>.
        /// </summary>
        /// <param name="source">The image to process.</param>
        /// <returns>A processed bitmap.</returns>
        public Bitmap ProcessFilter(Image source)
        {
            int width = source.Width;
            int height = source.Height;
            int maxWidth = width + 1;
            int maxHeight = height + 1;
            int bufferedWidth = width + 2;
            int bufferedHeight = height + 2;

            Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
            Bitmap input = new Bitmap(bufferedWidth, bufferedHeight, PixelFormat.Format32bppPArgb);
            destination.SetResolution(source.HorizontalResolution, source.VerticalResolution);
            input.SetResolution(source.HorizontalResolution, source.VerticalResolution);

            using (Graphics graphics = Graphics.FromImage(input))
            {
                // Fixes an issue with transparency not converting properly.
                graphics.Clear(Color.Transparent);

                Rectangle destinationRectangle = new Rectangle(0, 0, bufferedWidth, bufferedHeight);
                Rectangle rectangle = new Rectangle(0, 0, width, height);

                // If it's greyscale apply a colormatrix to the image.
                using (ImageAttributes attributes = new ImageAttributes())
                {
                    if (this.greyscale)
                    {
                        attributes.SetColorMatrix(ColorMatrixes.GreyScale);
                    }

                    // We use a trick here to detect right to the edges of the image.
                    // flip/tile the image with a pixel in excess in each direction to duplicate pixels.
                    // Later on we draw pixels without that excess.
                    using (TextureBrush tb = new TextureBrush(source, rectangle, attributes))
                    {
                        tb.WrapMode = WrapMode.TileFlipXY;
                        tb.TranslateTransform(1, 1);

                        graphics.FillRectangle(tb, destinationRectangle);
                    }
                }
            }

            try
            {
                double[,] horizontalFilter = this.edgeFilter.HorizontalGradientOperator;

                int kernelLength = horizontalFilter.GetLength(0);
                int radius = kernelLength >> 1;

                using (FastBitmap sourceBitmap = new FastBitmap(input))
                {
                    using (FastBitmap destinationBitmap = new FastBitmap(destination))
                    {
                        // Loop through the pixels.
                        Parallel.For(
                            0,
                            bufferedHeight,
                            y =>
                            {
                                for (int x = 0; x < bufferedWidth; x++)
                                {
                                    double rX = 0;
                                    double gX = 0;
                                    double bX = 0;

                                    // Apply each matrix multiplier to the color components for each pixel.
                                    for (int fy = 0; fy < kernelLength; fy++)
                                    {
                                        int fyr = fy - radius;
                                        int offsetY = y + fyr;

                                        // Skip the current row
                                        if (offsetY < 0)
                                        {
                                            continue;
                                        }

                                        // Outwith the current bounds so break.
                                        if (offsetY >= bufferedHeight)
                                        {
                                            break;
                                        }

                                        for (int fx = 0; fx < kernelLength; fx++)
                                        {
                                            int fxr = fx - radius;
                                            int offsetX = x + fxr;

                                            // Skip the column
                                            if (offsetX < 0)
                                            {
                                                continue;
                                            }

                                            if (offsetX < bufferedWidth)
                                            {
                                                // ReSharper disable once AccessToDisposedClosure
                                                Color currentColor = sourceBitmap.GetPixel(offsetX, offsetY);
                                                double r = currentColor.R;
                                                double g = currentColor.G;
                                                double b = currentColor.B;

                                                rX += horizontalFilter[fy, fx] * r;

                                                gX += horizontalFilter[fy, fx] * g;

                                                bX += horizontalFilter[fy, fx] * b;
                                            }
                                        }
                                    }

                                    // Apply the equation and sanitize.
                                    byte red = rX.ToByte();
                                    byte green = gX.ToByte();
                                    byte blue = bX.ToByte();

                                    Color newColor = Color.FromArgb(red, green, blue);
                                    if (y > 0 && x > 0 && y < maxHeight && x < maxWidth)
                                    {
                                        // ReSharper disable once AccessToDisposedClosure
                                        destinationBitmap.SetPixel(x - 1, y - 1, newColor);
                                    }
                                }
                            });
                    }
                }
            }
            finally
            {
                // We created a new image. Cleanup.
                input.Dispose();
            }

            return destination;
        }
Example #29
0
        void Convert2DTo1D( TerrainAtlas2D atlas2D, int atlasesCount, int atlas1DHeight )
        {
            TexIds = new int[atlasesCount];
            Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, elementsPerAtlas1D );
            int index = 0;

            using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true, true ) ) {
                for( int i = 0; i < TexIds.Length; i++ )
                    Make1DTexture( i, atlas, atlas2D, atlas1DHeight, ref index );
            }
        }
 private static void PutPixel(FastBitmap bmp, int index, Color color)
 {
     if (color.A > 0)
     {
         int x = index % bmp.Width;
         int y = index / bmp.Width;
         if (x < bmp.Width && y < bmp.Height)
             bmp.SetPixel(x, y, color);
     }
 }
Example #31
0
 void Make1DTexture( int i, FastBitmap atlas, TerrainAtlas2D atlas2D, int atlas1DHeight, ref int index )
 {
     int elemSize = atlas2D.elementSize;
     using( Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight ) )
         using( FastBitmap dst = new FastBitmap( atlas1d, true, false ) )
     {
         for( int index1D = 0; index1D < elementsPerAtlas1D; index1D++ ) {
             FastBitmap.MovePortion( (index & 0x0F) * elemSize, (index >> 4) * elemSize,
                                    0, index1D * elemSize, atlas, dst, elemSize );
             index++;
         }
         TexIds[i] = graphics.CreateTexture( dst );
     }
 }