// 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)); }
// 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); }
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); }
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; }