mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-10-27 22:42:38 +01:00
OCR -Image splitting now a bit faster
git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@2090 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
parent
f945f00e5a
commit
31cdbbf416
@ -1351,7 +1351,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
private static NOcrChar NOcrFindExpandedMatch(Bitmap parentBitmap, ImageSplitterItem targetItem, int topMargin, List<NOcrChar> nOcrChars)
|
||||
{
|
||||
var nbmp = new NikseBitmap(parentBitmap);
|
||||
int w = targetItem.Bitmap.Width;
|
||||
int w = targetItem.NikseBitmap.Width;
|
||||
int index = 0;
|
||||
foreach (NOcrChar oc in nOcrChars)
|
||||
{
|
||||
@ -1455,7 +1455,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
private static NOcrChar NOcrFindBestMatch(Bitmap parentBitmap, ImageSplitterItem targetItem, int topMargin, out bool italic, List<NOcrChar> nOcrChars, double unItalicFactor, bool tryItalicScaling, bool deepSeek)
|
||||
{
|
||||
italic = false;
|
||||
var nbmp = new NikseBitmap(targetItem.Bitmap);
|
||||
var nbmp = targetItem.NikseBitmap;
|
||||
int index = 0;
|
||||
foreach (NOcrChar oc in nOcrChars)
|
||||
{
|
||||
@ -2158,23 +2158,23 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
// Fix uppercase/lowercase issues (not I/l)
|
||||
if (result.Text == "e")
|
||||
_nocrLastLowercaseHeight = targetItem.Bitmap.Height;
|
||||
_nocrLastLowercaseHeight = targetItem.NikseBitmap.Height;
|
||||
else if (_nocrLastLowercaseHeight == -1 && result.Text == "a")
|
||||
_nocrLastLowercaseHeight = targetItem.Bitmap.Height;
|
||||
_nocrLastLowercaseHeight = targetItem.NikseBitmap.Height;
|
||||
|
||||
if (result.Text == "E" || result.Text == "H" || result.Text == "R" || result.Text == "D" || result.Text == "T")
|
||||
_nocrLastUppercaseHeight = targetItem.Bitmap.Height;
|
||||
_nocrLastUppercaseHeight = targetItem.NikseBitmap.Height;
|
||||
else if (_nocrLastUppercaseHeight == -1 && result.Text == "M")
|
||||
_nocrLastUppercaseHeight = targetItem.Bitmap.Height;
|
||||
_nocrLastUppercaseHeight = targetItem.NikseBitmap.Height;
|
||||
|
||||
if (result.Text == "V" || result.Text == "W" || result.Text == "U" || result.Text == "S" || result.Text == "Z" || result.Text == "O" || result.Text == "X" || result.Text == "Ø" || result.Text == "C")
|
||||
{
|
||||
if (_nocrLastLowercaseHeight > 3 && targetItem.Bitmap.Height - _nocrLastLowercaseHeight < 2)
|
||||
if (_nocrLastLowercaseHeight > 3 && targetItem.NikseBitmap.Height - _nocrLastLowercaseHeight < 2)
|
||||
result.Text = result.Text.ToLower();
|
||||
}
|
||||
else if (result.Text == "v" || result.Text == "w" || result.Text == "u" || result.Text == "s" || result.Text == "z" || result.Text == "o" || result.Text == "x" || result.Text == "ø" || result.Text == "c")
|
||||
{
|
||||
if (_nocrLastUppercaseHeight > 3 && _nocrLastUppercaseHeight - targetItem.Bitmap.Height < 2)
|
||||
if (_nocrLastUppercaseHeight > 3 && _nocrLastUppercaseHeight - targetItem.NikseBitmap.Height < 2)
|
||||
result.Text = result.Text.ToUpper();
|
||||
}
|
||||
|
||||
@ -2197,23 +2197,23 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
// Fix uppercase/lowercase issues (not I/l)
|
||||
if (result.Text == "e")
|
||||
p.NOcrLastLowercaseHeight = targetItem.Bitmap.Height;
|
||||
p.NOcrLastLowercaseHeight = targetItem.NikseBitmap.Height;
|
||||
else if (p.NOcrLastLowercaseHeight == -1 && result.Text == "a")
|
||||
p.NOcrLastLowercaseHeight = targetItem.Bitmap.Height;
|
||||
p.NOcrLastLowercaseHeight = targetItem.NikseBitmap.Height;
|
||||
|
||||
if (result.Text == "E" || result.Text == "H" || result.Text == "R" || result.Text == "D" || result.Text == "T")
|
||||
p.NOcrLastUppercaseHeight = targetItem.Bitmap.Height;
|
||||
p.NOcrLastUppercaseHeight = targetItem.NikseBitmap.Height;
|
||||
else if (p.NOcrLastUppercaseHeight == -1 && result.Text == "M")
|
||||
p.NOcrLastUppercaseHeight = targetItem.Bitmap.Height;
|
||||
p.NOcrLastUppercaseHeight = targetItem.NikseBitmap.Height;
|
||||
|
||||
if (result.Text == "V" || result.Text == "W" || result.Text == "U" || result.Text == "S" || result.Text == "Z" || result.Text == "O" || result.Text == "X" || result.Text == "Ø" || result.Text == "C")
|
||||
{
|
||||
if (p.NOcrLastLowercaseHeight > 3 && targetItem.Bitmap.Height - p.NOcrLastLowercaseHeight < 2)
|
||||
if (p.NOcrLastLowercaseHeight > 3 && targetItem.NikseBitmap.Height - p.NOcrLastLowercaseHeight < 2)
|
||||
result.Text = result.Text.ToLower();
|
||||
}
|
||||
else if (result.Text == "v" || result.Text == "w" || result.Text == "u" || result.Text == "s" || result.Text == "z" || result.Text == "o" || result.Text == "x" || result.Text == "ø" || result.Text == "c")
|
||||
{
|
||||
if (p.NOcrLastUppercaseHeight > 3 && p.NOcrLastUppercaseHeight - targetItem.Bitmap.Height < 2)
|
||||
if (p.NOcrLastUppercaseHeight > 3 && p.NOcrLastUppercaseHeight - targetItem.NikseBitmap.Height < 2)
|
||||
result.Text = result.Text.ToUpper();
|
||||
}
|
||||
|
||||
@ -2223,22 +2223,23 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
return new CompareMatch(result.Text, result.Italic, 0, null, result);
|
||||
}
|
||||
|
||||
private CompareMatch GetCompareMatch(ImageSplitterItem targetItem, Bitmap parentBitmap, out CompareMatch secondBestGuess)
|
||||
private CompareMatch GetCompareMatch(ImageSplitterItem targetItem, NikseBitmap parentBitmap, out CompareMatch secondBestGuess)
|
||||
{
|
||||
secondBestGuess = null;
|
||||
int index = 0;
|
||||
int smallestDifference = 10000;
|
||||
int smallestIndex = -1;
|
||||
Bitmap target = targetItem.Bitmap;
|
||||
NikseBitmap target = targetItem.NikseBitmap;
|
||||
|
||||
foreach (CompareItem compareItem in _compareBitmaps)
|
||||
{
|
||||
// check for expand match!
|
||||
if (compareItem.ExpandCount > 0 && compareItem.Bitmap.Width > targetItem.Bitmap.Width)
|
||||
if (compareItem.ExpandCount > 0 && compareItem.Bitmap.Width > target.Width &&
|
||||
parentBitmap.Width >= compareItem.Bitmap.Width + targetItem.X &&
|
||||
parentBitmap.Height >= compareItem.Bitmap.Height + targetItem.Y)
|
||||
{
|
||||
Bitmap cutBitmap = ImageSplitter.Copy(parentBitmap, new Rectangle(targetItem.X, targetItem.Y, compareItem.Bitmap.Width, compareItem.Bitmap.Height));
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, cutBitmap);
|
||||
cutBitmap.Dispose();
|
||||
var cutBitmap = parentBitmap.CopyRectangle(new Rectangle(targetItem.X, targetItem.Y, compareItem.Bitmap.Width, compareItem.Bitmap.Height));
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, cutBitmap);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2257,58 +2258,48 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
{
|
||||
if (smallestDifference > 0.9 && target.Width > 25)
|
||||
{
|
||||
Bitmap cutBitmap = CopyBitmapSection(target, new Rectangle(4, 0, target.Width - 4, target.Height));
|
||||
var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height));
|
||||
FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap);
|
||||
cutBitmap.Dispose();
|
||||
double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height);
|
||||
}
|
||||
|
||||
|
||||
if (smallestDifference > 0 && target.Width > 12)
|
||||
{
|
||||
Bitmap cutBitmap = CopyBitmapSection(target, new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap);
|
||||
cutBitmap.Dispose();
|
||||
}
|
||||
|
||||
if (smallestDifference > 0 && target.Width > 12)
|
||||
{
|
||||
Bitmap cutBitmap = CopyBitmapSection(target, new Rectangle(0, 0, target.Width - 2, target.Height));
|
||||
var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height));
|
||||
FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap);
|
||||
cutBitmap.Dispose();
|
||||
}
|
||||
|
||||
if (smallestDifference > 0 && target.Width > 12)
|
||||
{
|
||||
Bitmap cutBitmap = CopyBitmapSection(target, new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
int topCrop = 0;
|
||||
Bitmap cutBitmap2 = ImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2);
|
||||
var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2);
|
||||
if (cutBitmap2.Height != target.Height)
|
||||
FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2);
|
||||
cutBitmap.Dispose();
|
||||
cutBitmap2.Dispose();
|
||||
}
|
||||
|
||||
if (smallestDifference > 0 && target.Width > 15)
|
||||
{
|
||||
Bitmap cutBitmap = CopyBitmapSection(target, new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
int topCrop = 0;
|
||||
Bitmap cutBitmap2 = ImageSplitter.CropTopAndBottom(cutBitmap, out topCrop);
|
||||
var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop);
|
||||
if (cutBitmap2.Height != target.Height)
|
||||
FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2);
|
||||
cutBitmap.Dispose();
|
||||
cutBitmap2.Dispose();
|
||||
}
|
||||
|
||||
if (smallestDifference > 0 && target.Width > 15)
|
||||
{
|
||||
Bitmap cutBitmap = CopyBitmapSection(target, new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height));
|
||||
int topCrop = 0;
|
||||
Bitmap cutBitmap2 = ImageSplitter.CropTopAndBottom(cutBitmap, out topCrop);
|
||||
var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop);
|
||||
if (cutBitmap2.Height != target.Height)
|
||||
FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2);
|
||||
cutBitmap.Dispose();
|
||||
cutBitmap2.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2378,9 +2369,8 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private void FindBestMatch(ref int index, ref int smallestDifference, ref int smallestIndex, Bitmap target2)
|
||||
private void FindBestMatch(ref int index, ref int smallestDifference, ref int smallestIndex, NikseBitmap target)
|
||||
{
|
||||
NikseBitmap target = new NikseBitmap(target2);
|
||||
int numberOfForegroundColors = CalculateNumberOfForegroundColors(target);
|
||||
int minForeColorMatch = 90;
|
||||
|
||||
@ -2396,7 +2386,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < 3)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2424,7 +2414,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < 40)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2454,7 +2444,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2480,7 +2470,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2506,7 +2496,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2532,7 +2522,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2558,7 +2548,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2584,7 +2574,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2610,7 +2600,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2636,7 +2626,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2662,7 +2652,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2688,7 +2678,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < minForeColorMatch)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -2716,6 +2706,8 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private unsafe static int CalculateNumberOfForegroundColors(NikseBitmap nikseBitmap)
|
||||
{
|
||||
int count = 0;
|
||||
@ -2810,7 +2802,8 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
if (threadText == null)
|
||||
{
|
||||
var matches = new List<CompareMatch>();
|
||||
List<ImageSplitterItem> list = ImageSplitter.SplitBitmapToLetters(bitmap, (int)numericUpDownPixelsIsSpace.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
NikseBitmap parentBitmap = new NikseBitmap(bitmap);
|
||||
List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(parentBitmap, (int)numericUpDownPixelsIsSpace.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
int index = 0;
|
||||
bool expandSelection = false;
|
||||
bool shrinkSelection = false;
|
||||
@ -2867,14 +2860,14 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
_italicCheckedLast = _vobSubOcrCharacter.IsItalic;
|
||||
|
||||
}
|
||||
else if (item.Bitmap == null)
|
||||
else if (item.NikseBitmap == null)
|
||||
{
|
||||
matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
CompareMatch bestGuess;
|
||||
CompareMatch match = GetCompareMatch(item, bitmap, out bestGuess);
|
||||
CompareMatch match = GetCompareMatch(item, parentBitmap, out bestGuess);
|
||||
if (match == null)
|
||||
{
|
||||
_vobSubOcrCharacter.Initialize(bitmap, item, _manualOcrDialogPosition, _italicCheckedLast, false, bestGuess, _lastAdditions, this);
|
||||
@ -3101,20 +3094,20 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
private void NOCRIntialize(Bitmap bitmap)
|
||||
{
|
||||
var matches = new List<CompareMatch>();
|
||||
List<ImageSplitterItem> list = ImageSplitter.SplitBitmapToLetters(bitmap, (int)numericUpDownNumberOfPixelsIsSpaceNOCR.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(new NikseBitmap(bitmap), (int)numericUpDownNumberOfPixelsIsSpaceNOCR.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
|
||||
foreach (ImageSplitterItem item in list)
|
||||
{
|
||||
if (item.Bitmap != null)
|
||||
if (item.NikseBitmap != null)
|
||||
{
|
||||
var old = item.Bitmap;
|
||||
var nbmp = new NikseBitmap(item.Bitmap);
|
||||
//var old = item.Bitmap;
|
||||
var nbmp = item.NikseBitmap;
|
||||
nbmp.ReplaceNonWhiteWithTransparent();
|
||||
item.Y += nbmp.CropTopTransparent(0);
|
||||
nbmp.CropTransparentSidesAndBottom(0, true);
|
||||
nbmp.ReplaceTransparentWith(Color.Black);
|
||||
item.Bitmap = nbmp.GetBitmap();
|
||||
old.Dispose();
|
||||
//item.Bitmap = nbmp.GetBitmap();
|
||||
//old.Dispose();
|
||||
|
||||
GetNOcrCompareMatch(item, bitmap, _nocrChars, _unItalicFactor, false, false);
|
||||
}
|
||||
@ -3131,25 +3124,21 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
line = _nocrThreadResults[listViewIndex];
|
||||
if (string.IsNullOrEmpty(line))
|
||||
{
|
||||
NikseBitmap nbmp = new NikseBitmap(bitmap);
|
||||
nbmp.ReplaceNonWhiteWithTransparent();
|
||||
bitmap = nbmp.GetBitmap();
|
||||
var nbmpInput = new NikseBitmap(bitmap);
|
||||
nbmpInput.ReplaceNonWhiteWithTransparent();
|
||||
//bitmap = nbmp.GetBitmap();
|
||||
|
||||
var matches = new List<CompareMatch>();
|
||||
List<ImageSplitterItem> list = ImageSplitter.SplitBitmapToLetters(bitmap, (int)numericUpDownNumberOfPixelsIsSpaceNOCR.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(nbmpInput, (int)numericUpDownNumberOfPixelsIsSpaceNOCR.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
|
||||
foreach (ImageSplitterItem item in list)
|
||||
{
|
||||
if (item.Bitmap != null)
|
||||
if (item.NikseBitmap != null)
|
||||
{
|
||||
var old = item.Bitmap;
|
||||
nbmp = new NikseBitmap(item.Bitmap);
|
||||
nbmp.ReplaceNonWhiteWithTransparent();
|
||||
item.Y += nbmp.CropTopTransparent(0);
|
||||
nbmp.CropTransparentSidesAndBottom(0, true);
|
||||
nbmp.ReplaceTransparentWith(Color.Black);
|
||||
item.Bitmap = nbmp.GetBitmap();
|
||||
old.Dispose();
|
||||
item.NikseBitmap.ReplaceNonWhiteWithTransparent();
|
||||
item.Y += item.NikseBitmap.CropTopTransparent(0);
|
||||
item.NikseBitmap.CropTransparentSidesAndBottom(0, true);
|
||||
item.NikseBitmap.ReplaceTransparentWith(Color.Black);
|
||||
}
|
||||
}
|
||||
int index = 0;
|
||||
@ -3173,16 +3162,12 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
expandSelectionList.Add(list[index]);
|
||||
}
|
||||
item = GetExpandedSelection(bitmap, expandSelectionList, checkBoxRightToLeft.Checked);
|
||||
if (item.Bitmap != null)
|
||||
if (item.NikseBitmap != null)
|
||||
{
|
||||
var old = item.Bitmap;
|
||||
nbmp = new NikseBitmap(item.Bitmap);
|
||||
nbmp.ReplaceNonWhiteWithTransparent();
|
||||
item.Y += nbmp.CropTopTransparent(0);
|
||||
nbmp.CropTransparentSidesAndBottom(0, true);
|
||||
nbmp.ReplaceTransparentWith(Color.Black);
|
||||
item.Bitmap = nbmp.GetBitmap();
|
||||
old.Dispose();
|
||||
item.NikseBitmap.ReplaceNonWhiteWithTransparent();
|
||||
item.Y += item.NikseBitmap.CropTopTransparent(0);
|
||||
item.NikseBitmap.CropTransparentSidesAndBottom(0, true);
|
||||
item.NikseBitmap.ReplaceTransparentWith(Color.Black);
|
||||
}
|
||||
|
||||
_vobSubOcrNOcrCharacter.Initialize(bitmap, item, _manualOcrDialogPosition, _italicCheckedLast, expandSelectionList.Count > 1, null, _lastAdditions, this);
|
||||
@ -3224,7 +3209,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
_italicCheckedLast = _vobSubOcrNOcrCharacter.IsItalic;
|
||||
|
||||
}
|
||||
else if (item.Bitmap == null)
|
||||
else if (item.NikseBitmap == null)
|
||||
{
|
||||
matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null));
|
||||
}
|
||||
@ -3796,21 +3781,21 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
e.Result = p;
|
||||
Bitmap bitmap = p.Picture;
|
||||
var matches = new List<CompareMatch>();
|
||||
List<ImageSplitterItem> lines = ImageSplitter.SplitVertical(bitmap);
|
||||
List<ImageSplitterItem> list = ImageSplitter.SplitBitmapToLetters(lines, p.NumberOfPixelsIsSpace, p.RightToLeft, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
List<ImageSplitterItem> lines = NikseBitmapImageSplitter.SplitVertical(bitmap);
|
||||
List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(lines, p.NumberOfPixelsIsSpace, p.RightToLeft, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
|
||||
int index = 0;
|
||||
int outerIndex = 0;
|
||||
while (outerIndex < list.Count)
|
||||
{
|
||||
ImageSplitterItem item = list[outerIndex];
|
||||
if (item.Bitmap == null)
|
||||
if (item.NikseBitmap == null)
|
||||
{
|
||||
matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
var target = new NikseBitmap(item.Bitmap);
|
||||
var target = item.NikseBitmap;
|
||||
int numberOfForegroundColors = CalculateNumberOfForegroundColors(target);
|
||||
|
||||
int smallestDifference = 10000;
|
||||
@ -3828,7 +3813,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < 30)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -3854,7 +3839,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < 50)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem.Bitmap);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -3882,7 +3867,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (Math.Abs(compareItem.NumberOfForegroundColors - numberOfForegroundColors) < 55)
|
||||
{
|
||||
int dif = ImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, target);
|
||||
if (dif < smallestDifference)
|
||||
{
|
||||
smallestDifference = dif;
|
||||
@ -3897,7 +3882,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
}
|
||||
|
||||
CompareMatch match = null;
|
||||
double differencePercentage = smallestDifference * 100.0 / (item.Bitmap.Width * item.Bitmap.Height);
|
||||
double differencePercentage = smallestDifference * 100.0 / (item.NikseBitmap.Width * item.NikseBitmap.Height);
|
||||
double maxDiff = (double)p.MaxErrorPercent;
|
||||
if (differencePercentage <= maxDiff)
|
||||
{
|
||||
@ -4027,10 +4012,10 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
var p = (NOcrThreadParameter)e.Argument;
|
||||
e.Result = p;
|
||||
|
||||
Bitmap bitmap = p.Picture;
|
||||
var nbmp = new NikseBitmap(bitmap);
|
||||
nbmp.ReplaceNonWhiteWithTransparent();
|
||||
bitmap = nbmp.GetBitmap();
|
||||
//Bitmap bitmap = p.Picture;
|
||||
var nbmpInput = new NikseBitmap(p.Picture);
|
||||
nbmpInput.ReplaceNonWhiteWithTransparent();
|
||||
// bitmap = nbmp.GetBitmap();
|
||||
|
||||
var matches = new List<CompareMatch>();
|
||||
int minLineHeight = p.NOcrLastLowercaseHeight;
|
||||
@ -4040,34 +4025,32 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
if (maxLineHeight < 10)
|
||||
minLineHeight = 80;
|
||||
|
||||
List<ImageSplitterItem> lines = ImageSplitter.SplitVertical(bitmap, minLineHeight);
|
||||
List<ImageSplitterItem> list = ImageSplitter.SplitBitmapToLetters(lines, p.NumberOfPixelsIsSpace, p.RightToLeft, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
List<ImageSplitterItem> lines = NikseBitmapImageSplitter.SplitVertical(nbmpInput, minLineHeight);
|
||||
List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(lines, p.NumberOfPixelsIsSpace, p.RightToLeft, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
|
||||
foreach (ImageSplitterItem item in list)
|
||||
{
|
||||
if (item.Bitmap != null)
|
||||
if (item.NikseBitmap != null)
|
||||
{
|
||||
var old = item.Bitmap;
|
||||
nbmp = new NikseBitmap(item.Bitmap);
|
||||
var nbmp = item.NikseBitmap;
|
||||
nbmp.ReplaceNonWhiteWithTransparent();
|
||||
item.Y += nbmp.CropTopTransparent(0);
|
||||
nbmp.CropTransparentSidesAndBottom(0, true);
|
||||
nbmp.ReplaceTransparentWith(Color.Black);
|
||||
item.Bitmap = nbmp.GetBitmap();
|
||||
old.Dispose();
|
||||
// item.Bitmap = nbmp.GetBitmap();
|
||||
}
|
||||
}
|
||||
int index = 0;
|
||||
while (index < list.Count)
|
||||
{
|
||||
ImageSplitterItem item = list[index];
|
||||
if (item.Bitmap == null)
|
||||
if (item.NikseBitmap == null)
|
||||
{
|
||||
matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
CompareMatch match = GetNOcrCompareMatch(item, bitmap, p);
|
||||
CompareMatch match = GetNOcrCompareMatch(item, nbmpInput.GetBitmap(), p);
|
||||
if (match == null)
|
||||
{
|
||||
//if (p.AdvancedItalicDetection)
|
||||
@ -6028,8 +6011,9 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
Cursor = Cursors.WaitCursor;
|
||||
Bitmap bitmap = GetSubtitleBitmap(subtitleListView1.SelectedItems[0].Index);
|
||||
NikseBitmap parentBitmap = new NikseBitmap(bitmap);
|
||||
var matches = new List<CompareMatch>();
|
||||
List<ImageSplitterItem> list = ImageSplitter.SplitBitmapToLetters(bitmap, (int)numericUpDownPixelsIsSpace.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(parentBitmap, (int)numericUpDownPixelsIsSpace.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom);
|
||||
int index = 0;
|
||||
var imageSources = new List<Bitmap>();
|
||||
while (index < list.Count)
|
||||
@ -6043,7 +6027,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
else
|
||||
{
|
||||
CompareMatch bestGuess;
|
||||
CompareMatch match = GetCompareMatch(item, bitmap, out bestGuess);
|
||||
CompareMatch match = GetCompareMatch(item, parentBitmap, out bestGuess);
|
||||
if (match == null)
|
||||
{
|
||||
matches.Add(new CompareMatch(Configuration.Settings.Language.VobSubOcr.NoMatch, false, 0, null));
|
||||
|
@ -7,7 +7,23 @@ namespace Nikse.SubtitleEdit.Logic
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int ParentY { get; set; }
|
||||
public Bitmap Bitmap { get; set; }
|
||||
public Bitmap Bitmap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NikseBitmap == null)
|
||||
return null;
|
||||
return NikseBitmap.GetBitmap();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
NikseBitmap = null;
|
||||
else
|
||||
NikseBitmap = new NikseBitmap(value);
|
||||
}
|
||||
}
|
||||
public NikseBitmap NikseBitmap { get; set; }
|
||||
public string SpecialCharacter { get; set; }
|
||||
|
||||
public ImageSplitterItem(int x, int y, Bitmap bitmap)
|
||||
@ -18,12 +34,20 @@ namespace Nikse.SubtitleEdit.Logic
|
||||
SpecialCharacter = null;
|
||||
}
|
||||
|
||||
public ImageSplitterItem(int x, int y, NikseBitmap bitmap)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
NikseBitmap = bitmap;
|
||||
SpecialCharacter = null;
|
||||
}
|
||||
|
||||
public ImageSplitterItem(string specialCharacter)
|
||||
{
|
||||
X = 0;
|
||||
Y = 0;
|
||||
SpecialCharacter = specialCharacter;
|
||||
Bitmap = null;
|
||||
NikseBitmap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,13 @@ namespace Nikse.SubtitleEdit.Logic
|
||||
_bitmapData = new byte[Width * Height * 4];
|
||||
}
|
||||
|
||||
public NikseBitmap(int width, int height, byte[] bitmapData)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
_bitmapData = bitmapData;
|
||||
}
|
||||
|
||||
public NikseBitmap(Bitmap inputBitmap)
|
||||
{
|
||||
if (inputBitmap == null)
|
||||
@ -892,5 +899,25 @@ namespace Nikse.SubtitleEdit.Logic
|
||||
return newBitmap;
|
||||
}
|
||||
|
||||
|
||||
public NikseBitmap CopyRectangle(Rectangle section)
|
||||
{
|
||||
if (section.Bottom > Height)
|
||||
section = new Rectangle(section.Left, section.Top, section.Width, Height - section.Top);
|
||||
if (section.Width + section.Left > Width)
|
||||
section = new Rectangle(section.Left, section.Top, Width - section.Left, section.Height);
|
||||
var newBitmapData = new byte[section.Width * section.Height * 4];
|
||||
int index = 0;
|
||||
for (int y = section.Top; y < section.Bottom; y++)
|
||||
{
|
||||
int pixelAddress = (section.Left * 4) + (y * 4 * Width);
|
||||
Buffer.BlockCopy(_bitmapData, pixelAddress, newBitmapData, index, 4 * section.Width);
|
||||
index += 4 * section.Width;
|
||||
}
|
||||
return new NikseBitmap(section.Width, section.Height, newBitmapData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
690
src/Logic/NikseBitmapImageSplitter.cs
Normal file
690
src/Logic/NikseBitmapImageSplitter.cs
Normal file
@ -0,0 +1,690 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic
|
||||
{
|
||||
public class NikseBitmapImageSplitter
|
||||
{
|
||||
public static bool IsColorClose(Color a, Color b, int tolerance)
|
||||
{
|
||||
if (a.A < 120 && b.A < 120)
|
||||
return true; // transparent
|
||||
|
||||
if (a.A > 250 && a.R > 90 && a.G > 90 && a.B > 90 &&
|
||||
b.A > 250 && b.R > 90 && b.G > 90 && b.B > 90)
|
||||
return true; // dark, non transparent
|
||||
|
||||
int diff = (a.R + a.G + a.B) - (b.R + b.G + b.B);
|
||||
return diff < tolerance && diff > -tolerance;
|
||||
}
|
||||
|
||||
public static NikseBitmap Copy(NikseBitmap sourceBitmap, Rectangle section)
|
||||
{
|
||||
return sourceBitmap.CopyRectangle(section);
|
||||
}
|
||||
|
||||
public static NikseBitmap CropTopAndBottom(NikseBitmap bmp, out int topCropping)
|
||||
{
|
||||
int startTop = 0;
|
||||
int maxTop = bmp.Height-2;
|
||||
if (maxTop > bmp.Height)
|
||||
maxTop = bmp.Height;
|
||||
for (int y = 0; y < maxTop; y++)
|
||||
{
|
||||
bool allTransparent = true;
|
||||
for (int x = 1; x < bmp.Width - 1; x++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A != 0)
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allTransparent)
|
||||
break;
|
||||
startTop++;
|
||||
}
|
||||
if (startTop > 9)
|
||||
startTop -= 5; // if top space > 9, then allways leave blank 5 pixels on top (so . is not confused with ').
|
||||
topCropping = startTop;
|
||||
|
||||
for (int y = bmp.Height-1; y > 3; y--)
|
||||
{
|
||||
bool allTransparent = true;
|
||||
for (int x = 1; x < bmp.Width-1; x++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A != 0)
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allTransparent == false)
|
||||
return Copy(bmp, new Rectangle(0, startTop, bmp.Width - 1, y-startTop+1));
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static NikseBitmap CropTopAndBottom(NikseBitmap bmp, out int topCropping, int maxDifferentPixelsOnLine)
|
||||
{
|
||||
int startTop = 0;
|
||||
int maxTop = bmp.Height - 2;
|
||||
if (maxTop > bmp.Height)
|
||||
maxTop = bmp.Height;
|
||||
|
||||
for (int y = 0; y < maxTop; y++)
|
||||
{
|
||||
int difference = 0;
|
||||
bool allTransparent = true;
|
||||
for (int x = 1; x < bmp.Width - 1; x++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A != 0)
|
||||
{
|
||||
difference++;
|
||||
if (difference >= maxDifferentPixelsOnLine)
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allTransparent)
|
||||
break;
|
||||
startTop++;
|
||||
}
|
||||
if (startTop > 9)
|
||||
startTop -= 5; // if top space > 9, then allways leave blank 5 pixels on top (so . is not confused with ').
|
||||
topCropping = startTop;
|
||||
|
||||
for (int y = bmp.Height - 1; y > 3; y--)
|
||||
{
|
||||
int difference = 0;
|
||||
bool allTransparent = true;
|
||||
for (int x = 1; x < bmp.Width - 1; x++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A != 0)
|
||||
{
|
||||
difference++;
|
||||
if (difference >= maxDifferentPixelsOnLine)
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allTransparent == false)
|
||||
return Copy(bmp, new Rectangle(0, startTop, bmp.Width - 1, y - startTop + 1));
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static List<ImageSplitterItem> SplitVertical(Bitmap bmp)
|
||||
{
|
||||
return SplitVertical(new NikseBitmap(bmp));
|
||||
}
|
||||
|
||||
public static List<ImageSplitterItem> SplitVertical(Bitmap bmp, int lineMinHeight)
|
||||
{
|
||||
return SplitVertical(new NikseBitmap(bmp), lineMinHeight);
|
||||
}
|
||||
|
||||
public static List<ImageSplitterItem> SplitVertical(NikseBitmap bmp)
|
||||
{ // split into lines
|
||||
int startY = 0;
|
||||
int size = 0;
|
||||
var parts = new List<ImageSplitterItem>();
|
||||
for (int y = 0; y < bmp.Height; y++)
|
||||
{
|
||||
bool allTransparent = true;
|
||||
for (int x = 0; x < bmp.Width; x++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A != 0)
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allTransparent)
|
||||
{
|
||||
if (size > 2 && size < 6)
|
||||
{
|
||||
size++; // at least 5 pixels, like top of 'i'
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size > 2)
|
||||
{
|
||||
NikseBitmap part = Copy(bmp, new Rectangle(0, startY, bmp.Width, size+1));
|
||||
// part.Save("c:\\line_0_to_width.bmp");
|
||||
parts.Add(new ImageSplitterItem(0, startY, part));
|
||||
// bmp.Save("c:\\original.bmp");
|
||||
}
|
||||
size = 0;
|
||||
startY = y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size++;
|
||||
}
|
||||
|
||||
}
|
||||
if (size > 2)
|
||||
{
|
||||
NikseBitmap part = Copy(bmp, new Rectangle(0, startY, bmp.Width, size+1));
|
||||
parts.Add(new ImageSplitterItem(0, startY, part));
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
public static List<ImageSplitterItem> SplitVertical(NikseBitmap bmp, int lineMinHeight)
|
||||
{ // split into lines
|
||||
int startY = 0;
|
||||
int size = 0;
|
||||
var parts = new List<ImageSplitterItem>();
|
||||
for (int y = 0; y < bmp.Height; y++)
|
||||
{
|
||||
bool allTransparent = true;
|
||||
for (int x = 0; x < bmp.Width; x++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A != 0)
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allTransparent)
|
||||
{
|
||||
if (size > 2 && size <= lineMinHeight)
|
||||
{
|
||||
size++; // at least 5 pixels, like top of 'i'
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size > 2)
|
||||
{
|
||||
NikseBitmap part = Copy(bmp, new Rectangle(0, startY, bmp.Width, size + 1));
|
||||
// part.Save("c:\\line_0_to_width.bmp");
|
||||
parts.Add(new ImageSplitterItem(0, startY, part));
|
||||
// bmp.Save("c:\\original.bmp");
|
||||
}
|
||||
size = 0;
|
||||
startY = y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size++;
|
||||
}
|
||||
|
||||
}
|
||||
if (size > 2)
|
||||
{
|
||||
NikseBitmap part = Copy(bmp, new Rectangle(0, startY, bmp.Width, size + 1));
|
||||
parts.Add(new ImageSplitterItem(0, startY, part));
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
public static int IsBitmapsAlike(Bitmap bmp1, Bitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
public static int IsBitmapsAlike(FastBitmap bmp1, Bitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
Color c1 = bmp1.GetPixel(x, y);
|
||||
Color c2 = bmp1.GetPixel(x, y);
|
||||
if (!IsColorClose(c1, c2, 20))
|
||||
different++;
|
||||
}
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
private static List<ImageSplitterItem> SplitHorizontal(ImageSplitterItem verticalItem, int xOrMorePixelsMakesSpace)
|
||||
{ // split line into letters
|
||||
NikseBitmap bmp = verticalItem.NikseBitmap;
|
||||
var parts = new List<ImageSplitterItem>();
|
||||
int size = 0;
|
||||
int startX = 0;
|
||||
int lastEndX = 0;
|
||||
int y = 0;
|
||||
bool spaceJustAdded = false;
|
||||
|
||||
for (int x = 0; x < bmp.Width - 1; x++)
|
||||
{
|
||||
bool allTransparent = IsVerticalLineTransparent(bmp, ref y, x);
|
||||
|
||||
// check if line is transparent and cursive
|
||||
bool cursiveOk = false;
|
||||
int tempY = 0;
|
||||
if (allTransparent == false &&
|
||||
size > 5 &&
|
||||
y > 3 &&
|
||||
x < bmp.Width-2 &&
|
||||
!IsVerticalLineTransparent(bmp, ref tempY, x + 1))
|
||||
{
|
||||
|
||||
//Add space?
|
||||
if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX)
|
||||
{
|
||||
int cleanCount = 0;
|
||||
for (int j = lastEndX; j < startX; j++)
|
||||
{
|
||||
int y1 = j;
|
||||
if (IsVerticalLineTransparent2(bmp, ref y1, j))
|
||||
cleanCount++;
|
||||
}
|
||||
if (cleanCount > 0 && !spaceJustAdded)
|
||||
{
|
||||
parts.Add(new ImageSplitterItem(" "));
|
||||
spaceJustAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
var cursivePoints = new List<Point>();
|
||||
|
||||
cursiveOk = IsCursiveVerticalLineTransparent(bmp, size, y, x, cursivePoints);
|
||||
|
||||
if (cursiveOk)
|
||||
{
|
||||
// make letter image
|
||||
int end = x + 1 - startX;
|
||||
if (startX > 0)
|
||||
{
|
||||
startX--;
|
||||
end++;
|
||||
}
|
||||
NikseBitmap b1 = Copy(bmp, new Rectangle(startX, 0, end, bmp.Height));
|
||||
// b1.Save(@"d:\temp\cursive.bmp"); // just for debugging
|
||||
|
||||
// make non-black/transparent stuff from other letter transparent
|
||||
foreach (Point p in cursivePoints)
|
||||
{
|
||||
for (int fixY = p.Y; fixY < bmp.Height; fixY++)
|
||||
b1.SetPixel(p.X - startX, fixY, Color.Transparent);
|
||||
}
|
||||
|
||||
RemoveBlackBarRight(b1);
|
||||
// b1.Save(@"d:\temp\cursive-cleaned.bmp"); // just for debugging
|
||||
|
||||
// crop and save image
|
||||
int addY;
|
||||
b1 = CropTopAndBottom(b1, out addY);
|
||||
parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, b1));
|
||||
spaceJustAdded = false;
|
||||
size = 0;
|
||||
startX = x + 1;
|
||||
lastEndX = x;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cursiveOk)
|
||||
{
|
||||
if (allTransparent)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
if (size > 1)
|
||||
{
|
||||
//Add space?
|
||||
if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX)
|
||||
{
|
||||
int cleanCount = 0;
|
||||
for (int j = lastEndX; j < startX; j++)
|
||||
{
|
||||
int y1=j;
|
||||
if (IsVerticalLineTransparent2(bmp, ref y1, j))
|
||||
cleanCount++;
|
||||
}
|
||||
if (cleanCount > 2 && !spaceJustAdded)
|
||||
{
|
||||
parts.Add(new ImageSplitterItem(" "));
|
||||
spaceJustAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (startX > 0)
|
||||
startX--;
|
||||
lastEndX = x;
|
||||
int end = x + 1 - startX;
|
||||
NikseBitmap part = Copy(bmp, new Rectangle(startX, 0, end, bmp.Height));
|
||||
RemoveBlackBarRight(part);
|
||||
int addY;
|
||||
// part.Save("c:\\before" + startX.ToString() + ".bmp"); // just for debugging
|
||||
part = CropTopAndBottom(part, out addY);
|
||||
// part.Save("c:\\after" + startX.ToString() + ".bmp"); // just for debugging
|
||||
parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, part));
|
||||
spaceJustAdded = false;
|
||||
// part.Save(@"d:\temp\cursive.bmp"); // just for debugging
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
startX = x + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX && !spaceJustAdded)
|
||||
parts.Add(new ImageSplitterItem(" "));
|
||||
|
||||
if (startX > 0)
|
||||
startX--;
|
||||
lastEndX = bmp.Width-1;
|
||||
int end = lastEndX + 1 - startX;
|
||||
NikseBitmap part = Copy(bmp, new Rectangle(startX, 0, end, bmp.Height - 1));
|
||||
int addY;
|
||||
part = CropTopAndBottom(part, out addY);
|
||||
parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, part));
|
||||
//part.Save(@"d:\temp\cursive.bmp"); // just for debugging
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
private static void RemoveBlackBarRight(NikseBitmap bmp)
|
||||
{
|
||||
int xRemoveBlackBar = bmp.Width-1;
|
||||
for (int yRemoveBlackBar = 0; yRemoveBlackBar < bmp.Height; yRemoveBlackBar++)
|
||||
{
|
||||
Color c = bmp.GetPixel(xRemoveBlackBar, yRemoveBlackBar);
|
||||
if (c.A == 0 || IsColorClose(c, Color.Black, 280))
|
||||
{
|
||||
if (bmp.GetPixel(xRemoveBlackBar - 1, yRemoveBlackBar).A == 0)
|
||||
bmp.SetPixel(xRemoveBlackBar, yRemoveBlackBar, Color.Transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsCursiveVerticalLineTransparent(NikseBitmap bmp, int size, int y, int x, List<Point> cursivePoints)
|
||||
{
|
||||
bool cursiveOk = true;
|
||||
int newY = y;
|
||||
int newX = x;
|
||||
while (cursiveOk && newY < bmp.Height - 1)
|
||||
{
|
||||
Color c0 = bmp.GetPixel(newX, newY);
|
||||
if (c0.A == 0 || IsColorClose(c0, Color.Black, 280))
|
||||
{
|
||||
newY++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Color c1 = bmp.GetPixel(newX - 1, newY - 1);
|
||||
Color c2 = bmp.GetPixel(newX - 1, newY);
|
||||
if ((c1.A == 0 || IsColorClose(c1, Color.Black, 280)) && // still dark color...
|
||||
(c2.A == 0 || IsColorClose(c2, Color.Black, 280)))
|
||||
{
|
||||
cursivePoints.Add(new Point(newX, newY));
|
||||
if (newX > 1)
|
||||
newX--;
|
||||
else
|
||||
cursiveOk = false;
|
||||
|
||||
newY++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursiveOk = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (newX < x - size)
|
||||
cursiveOk = false;
|
||||
}
|
||||
return cursiveOk;
|
||||
}
|
||||
|
||||
private static bool IsVerticalLineTransparent(NikseBitmap bmp, ref int y, int x)
|
||||
{
|
||||
bool allTransparent = true;
|
||||
for (y = 0; y < bmp.Height - 1; y++)
|
||||
{
|
||||
Color c = bmp.GetPixel(x, y);
|
||||
if (c.A == 0 || //c.ToArgb() == transparentColor.ToArgb() ||
|
||||
IsColorClose(c, Color.Black, 280)) // still dark color...
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return allTransparent;
|
||||
}
|
||||
|
||||
private static bool IsVerticalLineTransparent2(NikseBitmap bmp, ref int y, int x)
|
||||
{
|
||||
bool allTransparent = true;
|
||||
for (y = 0; y < bmp.Height - 1; y++)
|
||||
{
|
||||
int a = bmp.GetAlpha(x, y);
|
||||
if (a == 0) // still dark color...
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
allTransparent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return allTransparent;
|
||||
}
|
||||
|
||||
public static List<ImageSplitterItem> SplitBitmapToLetters(NikseBitmap bmp, int xOrMorePixelsMakesSpace, bool rightToLeft, bool topToBottom)
|
||||
{
|
||||
var list = new List<ImageSplitterItem>();
|
||||
|
||||
// split into seperate lines
|
||||
List<ImageSplitterItem> verticalBitmaps = SplitVertical(bmp, xOrMorePixelsMakesSpace);
|
||||
|
||||
if (!topToBottom)
|
||||
verticalBitmaps.Reverse();
|
||||
|
||||
// split into letters
|
||||
int lineCount = 0;
|
||||
foreach (ImageSplitterItem b in verticalBitmaps)
|
||||
{
|
||||
if (lineCount > 0)
|
||||
list.Add(new ImageSplitterItem(Environment.NewLine));
|
||||
var line = new List<ImageSplitterItem>();
|
||||
foreach (ImageSplitterItem item in SplitHorizontal(b, xOrMorePixelsMakesSpace))
|
||||
{
|
||||
item.ParentY = item.Y;
|
||||
line.Add(item);
|
||||
}
|
||||
if (rightToLeft)
|
||||
line.Reverse();
|
||||
foreach (ImageSplitterItem item in line)
|
||||
list.Add(item);
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<ImageSplitterItem> SplitBitmapToLetters(List<ImageSplitterItem> verticalBitmaps, int xOrMorePixelsMakesSpace, bool rightToLeft, bool topToBottom)
|
||||
{
|
||||
var list = new List<ImageSplitterItem>();
|
||||
if (!topToBottom)
|
||||
verticalBitmaps.Reverse();
|
||||
|
||||
// split into letters
|
||||
int lineCount = 0;
|
||||
foreach (ImageSplitterItem b in verticalBitmaps)
|
||||
{
|
||||
if (lineCount > 0)
|
||||
list.Add(new ImageSplitterItem(Environment.NewLine));
|
||||
var line = new List<ImageSplitterItem>();
|
||||
foreach (ImageSplitterItem item in SplitHorizontal(b, xOrMorePixelsMakesSpace))
|
||||
{
|
||||
item.ParentY = item.Y;
|
||||
line.Add(item);
|
||||
}
|
||||
if (rightToLeft)
|
||||
line.Reverse();
|
||||
foreach (ImageSplitterItem item in line)
|
||||
list.Add(item);
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
internal static unsafe int IsBitmapsAlike(NikseBitmap bmp1, NikseBitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
internal static unsafe int IsBitmapsAlike(ManagedBitmap bmp1, NikseBitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
internal static unsafe int IsBitmapsAlike(ManagedBitmap bmp1, Bitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
internal static unsafe int IsBitmapsAlike(NikseBitmap bmp1, ManagedBitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
internal static unsafe int IsBitmapsAlike(Bitmap bmp1, NikseBitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
NikseBitmap nbmp1 = new NikseBitmap(bmp1);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(nbmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
|
||||
internal static unsafe int IsBitmapsAlike(NikseBitmap bmp1, Bitmap bmp2)
|
||||
{
|
||||
int different = 0;
|
||||
int maxDiff = (int)(bmp1.Width * bmp1.Height / 5.0);
|
||||
|
||||
for (int x = 1; x < bmp1.Width; x++)
|
||||
{
|
||||
for (int y = 1; y < bmp1.Height; y++)
|
||||
{
|
||||
if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
|
||||
{
|
||||
different++;
|
||||
}
|
||||
}
|
||||
if (different > maxDiff)
|
||||
return different + 10;
|
||||
}
|
||||
return different;
|
||||
}
|
||||
}
|
||||
}
|
@ -734,6 +734,7 @@
|
||||
<Compile Include="Logic\BluRaySup\PaletteInfo.cs" />
|
||||
<Compile Include="Logic\BluRaySup\ToolBox.cs" />
|
||||
<Compile Include="Logic\BmpReader.cs" />
|
||||
<Compile Include="Logic\NikseBitmapImageSplitter.cs" />
|
||||
<Compile Include="Logic\DetectEncoding\EncodingTools.cs" />
|
||||
<Compile Include="Logic\DetectEncoding\Multilang\CMLangConvertCharset.cs" />
|
||||
<Compile Include="Logic\DetectEncoding\Multilang\CMLangConvertCharsetClass.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user