Пример #1
0
        // extracts the actual title from a title frame
        public static Bitmap ExtractItemTitle(Bitmap bmp)
        {
            // first, flood-fill the actual item frame to remove it
            using (var data = new LockData(bmp))
            {
                var w = data.Width;
                var h = data.Height;

                // we start at all border points to make sure we remove the
                // full border, and not just a part of it
                for (var x = 0; x < w; x++)
                {
                    TraverseFill(data, x, 0);
                    TraverseFill(data, x, h - 1);
                }

                for (var y = 0; y < h; y++)
                {
                    TraverseFill(data, 0, y);
                    TraverseFill(data, w - 1, y);
                }
            }

            // then, convert the image to grayscale and reduce the brightness
            // by 0.26 to get rid of the background color gradient
            var gray = ConvertToGrayscale(bmp);

            // we detect the name by simply looking for any non-black pixels
            // that are left after flood-filling the outer frame and removing
            // the name background
            // "inner" refers to the rectangle containing only the item name
            int innerTop, innerLeft, innerBottom, innerRight;

            using (var data = new LockData(gray))
            {
                var w = data.Width;
                var h = data.Height;

                innerTop    = Helper.Range(0, h - 1).First(y => !data.IsRowBlack(y));
                innerBottom = Helper.Range(h - 1, 0, -1).First(y => !data.IsRowBlack(y));

                innerLeft = Helper.Range(0, w - 1).First(x =>
                                                         !data.IsColumnBlack(x, innerTop, innerBottom));
                innerRight = Helper.Range(w - 1, 0, -1).First(x =>
                                                              !data.IsColumnBlack(x, innerTop, innerBottom));
            }

            var nameFrame = new Rectangle(innerLeft, innerTop,
                                          innerRight - innerLeft + 1, innerBottom - innerTop + 1);

            // and copy the name with font anti-aliasing
            return(CopyName(bmp, gray, nameFrame));
        }
Пример #2
0
        public static Bitmap ExtractTitleFrame(Bitmap bmp)
        {
            int left, right, top, bottom;

            using (var data = new LockData(bmp))
            {
                var b = data.Height - 1;
                // first, remove the black border to the left and right
                left = Helper.Range(0, data.Width - 1).First(x =>
                                                             !data.IsColumnBlack(x, 0, b, MaxSkip));
                // for the right border, we can't check from top to bottom because
                // linked items have a non-black [X] at the top right, so we only
                // check the bottom half
                right = Helper.Range(data.Width - 2, 0, -1).First(x =>
                                                                  !data.IsColumnBlack(x, data.Height / 2, b, MaxSkip)) + 1;

                // to separate the title from the actual item, simplify move down
                // from the first non-black row until everything is black again.
                // we don't check the full width to work around the [X] on linked
                // items again. additionally, we skip a few pixels to the left,
                // as there's sometimes some semi-black border left
                top = Helper.Range(0, b).First(y =>
                                               data.IsRowNonBlack(y, left + 2, data.Width / 2)) - 1;

                // this is the first black row below the title, so the the title
                // height is given as bottom - top, not bottom - top + 1
                bottom = Helper.Range(top + 1, b).First(y =>
                                                        data.IsRowBlack(y, left, right));

                // remove any left-over semi-black border columns
                left = Helper.Range(left, data.Width - 1).First(x =>
                                                                data.IsColumnNonBlack(x, top + 1, bottom - 1));
                right = Helper.Range(right, 0, -1).First(x =>
                                                         data.IsColumnNonBlack(x, top + 1, bottom - 1)) + 1;
            }

            var width  = right - left;
            var height = bottom - top;

            var targetFrame = new Rectangle(left, top, width, height);

            var title = new Bitmap(width, height, PixelFormat.Format24bppRgb);

            using (Graphics g = Graphics.FromImage(title))
            {
                g.DrawImage(bmp, new Rectangle(0, 0, width, height), targetFrame,
                            GraphicsUnit.Pixel);
            }

            return(title);
        }
Пример #3
0
        private Rectangle SelectFrame(Bitmap bmp, Point p)
        {
            var skip = 0;

            var top    = 0;
            var bottom = 0;

            var rect = new Rectangle(p.X, 0, 1, bmp.Height);

            using (var data = new LockData(bmp, rect))
            {
                if (!data.IsBlackAt(0, p.Y))
                {
                    return(new Rectangle());
                }

                top = Helper.Range(p.Y, 0, -1)
                      .TakeWhile(y => data.IsBlackAt(0, y) ||
                                 skip++ < MaxSkip)
                      .Last(y => data.IsBlackAt(0, y));

                skip   = 0;
                bottom = Helper.Range(p.Y, bmp.Height - 1)
                         .TakeWhile(y => data.IsBlackAt(0, y) ||
                                    skip++ < MaxSkip)
                         .Last(y => data.IsBlackAt(0, y));
            }

            var border = FindBorder(bmp, new Point(p.X, bottom));
            var left   = border.Left;

            // verify the left border is indeed black
            var leftRect = new Rectangle(left, 0, 1, bmp.Height);

            using (var data = new LockData(bmp, leftRect))
            {
                if (!data.IsColumnBlack(0, top, bottom, MaxSkip))
                {
                    return(new Rectangle());
                }
            }

            return(new Rectangle(left, top, border.Width, bottom - top + 1));
        }
Пример #4
0
        // extracts the actual title from a title frame
        public static Bitmap ExtractItemTitle(Bitmap bmp)
        {
            // first, flood-fill the actual item frame to remove it
            using (var data = new LockData(bmp))
            {
                var w = data.Width;
                var h = data.Height;

                // we start at all border points to make sure we remove the
                // full border, and not just a part of it
                for (var x = 0; x < w; x++)
                {
                    TraverseFill(data, x, 0);
                    TraverseFill(data, x, h - 1);
                }

                for (var y = 0; y < h; y++)
                {
                    TraverseFill(data, 0, y);
                    TraverseFill(data, w - 1, y);
                }
            }

            // then, convert the image to grayscale and reduce the brightness
            // by 0.26 to get rid of the background color gradient
            var gray = ConvertToGrayscale(bmp);

            // we detect the name by simply looking for any non-black pixels
            // that are left after flood-filling the outer frame and removing
            // the name background
            // "inner" refers to the rectangle containing only the item name
            int innerTop, innerLeft, innerBottom, innerRight;
            using (var data = new LockData(gray))
            {
                var w = data.Width;
                var h = data.Height;

                innerTop = Helper.Range(0, h - 1).First(y => !data.IsRowBlack(y));
                innerBottom = Helper.Range(h - 1, 0, -1).First(y => !data.IsRowBlack(y));

                innerLeft = Helper.Range(0, w - 1).First(x =>
                    !data.IsColumnBlack(x, innerTop, innerBottom));
                innerRight = Helper.Range(w - 1, 0, -1).First(x =>
                    !data.IsColumnBlack(x, innerTop, innerBottom));
            }

            var nameFrame = new Rectangle(innerLeft, innerTop,
                innerRight - innerLeft + 1, innerBottom - innerTop + 1);

            // and copy the name with font anti-aliasing
            return CopyName(bmp, gray, nameFrame);
        }
Пример #5
0
        private Rectangle SelectFrame(Bitmap bmp, Point p)
        {
            var skip = 0;

            var top = 0;
            var bottom = 0;

            var rect = new Rectangle(p.X, 0, 1, bmp.Height);
            using (var data = new LockData(bmp, rect))
            {
                if (!data.IsBlackAt(0, p.Y)) return new Rectangle();

                top = Helper.Range(p.Y, 0, -1)
                        .TakeWhile(y => data.IsBlackAt(0, y) ||
                            skip++ < MaxSkip)
                        .Last(y => data.IsBlackAt(0, y));

                skip = 0;
                bottom = Helper.Range(p.Y, bmp.Height - 1)
                        .TakeWhile(y => data.IsBlackAt(0, y) ||
                            skip++ < MaxSkip)
                        .Last(y => data.IsBlackAt(0, y));
            }

            var border = FindBorder(bmp, new Point(p.X, bottom));
            var left = border.Left;

            // verify the left border is indeed black
            var leftRect = new Rectangle(left, 0, 1, bmp.Height);
            using (var data = new LockData(bmp, leftRect))
            {
                if (!data.IsColumnBlack(0, top, bottom, MaxSkip))
                    return new Rectangle();
            }

            return new Rectangle(left, top, border.Width, bottom - top + 1);
        }
Пример #6
0
        public static Bitmap ExtractTitleFrame(Bitmap bmp)
        {
            int left, right, top, bottom;
            using (var data = new LockData(bmp))
            {
                var b = data.Height - 1;
                // first, remove the black border to the left and right
                left = Helper.Range(0, data.Width - 1).First(x =>
                    !data.IsColumnBlack(x, 0, b, MaxSkip));
                // for the right border, we can't check from top to bottom because
                // linked items have a non-black [X] at the top right, so we only
                // check the bottom half
                right = Helper.Range(data.Width - 2, 0, -1).First(x =>
                    !data.IsColumnBlack(x, data.Height / 2, b, MaxSkip)) + 1;

                // to separate the title from the actual item, simplify move down
                // from the first non-black row until everything is black again.
                // we don't check the full width to work around the [X] on linked
                // items again. additionally, we skip a few pixels to the left,
                // as there's sometimes some semi-black border left
                top = Helper.Range(0, b).First(y =>
                    data.IsRowNonBlack(y, left + 2, data.Width / 2)) - 1;

                // this is the first black row below the title, so the the title
                // height is given as bottom - top, not bottom - top + 1
                bottom = Helper.Range(top + 1, b).First(y =>
                    data.IsRowBlack(y, left, right));

                // remove any left-over semi-black border columns
                left = Helper.Range(left, data.Width - 1).First(x =>
                    data.IsColumnNonBlack(x, top + 1, bottom - 1));
                right = Helper.Range(right, 0, -1).First(x =>
                    data.IsColumnNonBlack(x, top + 1, bottom - 1)) + 1;
            }

            var width = right - left;
            var height = bottom - top;

            var targetFrame = new Rectangle(left, top, width, height);

            var title = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            using (Graphics g = Graphics.FromImage(title))
            {
                g.DrawImage(bmp, new Rectangle(0, 0, width, height), targetFrame,
                    GraphicsUnit.Pixel);
            }

            return title;
        }