コード例 #1
0
        public static void ReadBitmap(MemoryStream image, int width, int height, int newWidth, int newHeight, float resReduce, int zoneRows, int zoneColumns, PixelZone[] zones,
                                      PixelZonesTotals zoneTotals, int bitDepth = 4, MemoryStream resizeStream = null, MemoryStream cropStream = null, SixLabors.ImageSharp.Rectangle?bitmapRect = null)
        {
            var start = DateTime.UtcNow;

            //Reset zones
            zoneTotals.ResetAverages();

            var useImage = image;

            //If this is passed it is expected that the zones passed are also based on this reduced resolution for now.
            // As the other comment below mentions maybe look into a better way of determining how reading the bitmap figures
            // out what zone to add values to.
            if (bitmapRect.HasValue)
            {
                useImage = ImageHandler.CropImageRect(useImage, width, height, cropStream, bitmapRect.Value, PixelFormat.Bgr32);
                width    = bitmapRect.Value.Width;
                height   = bitmapRect.Value.Height;
            }

            var t = DateTime.UtcNow;

            //It is expected that if we have a crop rect that newWidth and newHeight will be the values that would be reduced from the crop.
            // and that resizeStream is the correct length for these values.
            //Reducing the resolution of the desktop capture takes time but it saves a lot of time on reading the image
            //TODO: Investigate just skipping this and reading the bitmap as a function of the reduce resolution value as it would
            // effectivly produce the same result as point sampling to a lower resolution first. This could save memory pressure from
            // rescaling the image. But it may make determining what zone to add values to more complicated.
            if (width != newWidth || height != newHeight)
            {
                useImage = ImageHandler.ResizeImage(useImage, width, height, resizeStream, newWidth, newHeight, pixelFormat: PixelFormat.Bgr32);
            }
            //Console.WriteLine($"Resize Time:        {(DateTime.UtcNow - t).TotalMilliseconds}");

            //System.Threading.Tasks.Task.Run(() => ImageHandler.WriteImageToFile(useImage, newWidth, newHeight, $"Images/{DateTime.Now.Ticks.ToString().PadLeft(5, '0')}.png", pixelFormat: PixelFormat.Bgr32));

            t = DateTime.UtcNow;

            unsafe
            {
                var t1 = DateTime.UtcNow;

                fixed(byte *p = &(useImage.GetBuffer()[0]))
                {
                    long pos = 0;

                    fixed(PixelZone *z = &zones[0])
                    {
                        for (var i = 0; i < zones.Length; ++i)
                        {
                            for (var j = 0; j < z[i].Height; ++j)
                            {
                                for (var k = 0; k < z[i].PixelRanges[j].Length; k += bitDepth)
                                {
                                    //Colors are in BGRA32 format
                                    pos = z[i].PixelRanges[j].Start + k;
                                    *z[i].TotalB += p[pos];
                                    *z[i].TotalG += p[pos + 1];
                                    *z[i].TotalR += p[pos + 2];
                                    *z[i].Count  += 1;
                                }
                            }
                        }
                    }
                }

                //Console.WriteLine($"Read Bitmap Time:  {(DateTime.UtcNow - t1).TotalMilliseconds}");
            }
        }
コード例 #2
0
        public PixelZone(int row, int column, int xMin, int xMax, int yMin, int yMax, int stride, int bitDepth, PixelZonesTotals totals, int totalsIndex)
        {
            Row         = row;
            Column      = column;
            TopLeft     = new Point(xMin, yMin);
            BottomRight = new Point(xMax, yMax);
            Width       = BottomRight.X - TopLeft.X;
            Height      = BottomRight.Y - TopLeft.Y;
            TotalR      = totals.TotalR + totalsIndex;
            TotalG      = totals.TotalG + totalsIndex;
            TotalB      = totals.TotalB + totalsIndex;
            Count       = totals.Count + totalsIndex;
            AvgR        = totals.AvgR + totalsIndex;
            AvgG        = totals.AvgG + totalsIndex;
            AvgB        = totals.AvgB + totalsIndex;

            //The zones cover a rectangular area of the image, but the images are stored in a sequential array, so we need to have a range
            // for each y coordinate that the rectangle covers.
            nuint bytesLength = (nuint)(sizeof(ZonePixelRange) * Height);

            PixelRanges = (ZonePixelRange *)NativeMemory.Alloc(bytesLength);
            for (int y = TopLeft.Y, i = 0; y < BottomRight.Y; ++y, ++i)
            {
                var start  = GetImageCoordinate(stride, TopLeft.X, y, bitDepth);
                var length = GetImageCoordinate(stride, BottomRight.X, y, bitDepth) - start;
                PixelRanges[i] = new ZonePixelRange(start, length);
            }
        }