Пример #1
0
        /// <inheritdoc />
        public Bitmap Filter(Bitmap src)
        {
            if (src is null)
            {
                throw new ArgumentNullException(nameof(src));
            }
            if (src.PixelFormat != PixelFormat.Format32bppArgb)
            {
                throw new NotSupportedException(Errors.NotSupported);
            }

            var bitmapData = src.LockBits(
                new Rectangle(0, 0, src.Width, src.Height),
                ImageLockMode.ReadWrite, src.PixelFormat);

            var(width, height) = (src.Width, src.Height);
            var options = new ParallelOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };
            var step = Image.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8;

            unsafe
            {
                var startPtr = (byte *)bitmapData.Scan0.ToPointer();
                var stride   = bitmapData.Stride;

                Parallel.For(0, height, options, y =>
                {
                    //get the address of a row
                    var ptr = startPtr + y * stride;

                    for (int x = 0; x < width; ++x, ptr += step)
                    {
                        ptr[0] = ptr[1] = ptr[2] = (byte)_rec.GetLuma(
                            ref ptr[2], ref ptr[1], ref ptr[0]);
                    }
                });
            }

            src.UnlockBits(bitmapData);

            return(src);
        }
Пример #2
0
        /// <inheritdoc />
        public Bitmap Filter(Bitmap src)
        {
            if (src is null)
            {
                throw new ArgumentNullException(nameof(src));
            }
            if (src.PixelFormat != PixelFormat.Format32bppArgb)
            {
                throw new NotSupportedException(Errors.NotSupported);
            }

            var bitmapData = src.LockBits(
                new Rectangle(0, 0, src.Width, src.Height),
                ImageLockMode.ReadWrite, src.PixelFormat);

            var(width, height) = (src.Width, src.Height);
            var options = new ParallelOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };
            var step = Image.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8;

            unsafe
            {
                var startPtr = (byte *)bitmapData.Scan0.ToPointer();
                var stride   = bitmapData.Stride;

                var bag = new ConcurrentBag <double>();

                //get N luminance partial sums
                Parallel.For(0, height, options, () => 0.0, (y, state, partial) =>
                {
                    var ptr = startPtr + y * stride;

                    for (var x = 0; x < width; ++x, ptr += step)
                    {
                        partial += _rec.GetLuma(
                            ref ptr[2], ref ptr[1], ref ptr[0]
                            );
                    }

                    return(partial);
                },
                             (x) => bag.Add(x));

                //get luminance average
                var average = bag.Sum() / (width * height);

                Parallel.For(0, height, options, y =>
                {
                    var ptr = startPtr + y * stride;

                    for (var x = 0; x < width; ++x, ptr += step)
                    {
                        //if relative luminance greater or equal than average
                        //set it to white
                        if (_rec.GetLuma(ref ptr[2], ref ptr[1], ref ptr[0]) >= average)
                        {
                            ptr[0] = ptr[1] = ptr[2] = 255;
                        }
                        //else to black
                        else
                        {
                            ptr[0] = ptr[1] = ptr[2] = 0;
                        }
                    }
                });
            }

            src.UnlockBits(bitmapData);

            return(src);
        }