From cfddece8fa695351be7b8e94676c881260590e16 Mon Sep 17 00:00:00 2001 From: Nikolaj Olsson Date: Sat, 30 Apr 2016 10:56:44 +0200 Subject: [PATCH] Some improvements (fixed end-time + less splitting when using colors) for "Transport Stream" import - thx kurosu See #1728 --- LanguageMaster.xml | 2 +- libse/Language.cs | 2 +- libse/NikseBitmap.cs | 19 ++++++- .../TransportStream/TransportStreamParser.cs | 20 ++++++- src/Forms/VobSubOcr.cs | 52 ++++++++++++++----- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/LanguageMaster.xml b/LanguageMaster.xml index 57cbed17f..c1995b496 100644 --- a/LanguageMaster.xml +++ b/LanguageMaster.xml @@ -2177,7 +2177,7 @@ Keep changes? Min. alpha value (0=transparent, 255=fully visible) Transport stream Grayscale - Use color (will include some splitting of lines) + Use color (splitting of lines may occur) Prompt for unknown words Try to guess unknown words Auto break paragraph if more than two lines diff --git a/libse/Language.cs b/libse/Language.cs index abf85b03a..d3ef0f485 100644 --- a/libse/Language.cs +++ b/libse/Language.cs @@ -2493,7 +2493,7 @@ Keep changes?", TransparentMinAlpha = "Min. alpha value (0=transparent, 255=fully visible)", TransportStream = "Transport stream", TransportStreamGrayscale = "Grayscale", - TransportStreamGetColor = "Use color (will include some splitting of lines)", + TransportStreamGetColor = "Use color (splitting of lines may occur)", PromptForUnknownWords = "Prompt for unknown words", TryToGuessUnkownWords = "Try to guess unknown words", AutoBreakSubtitleIfMoreThanTwoLines = "Auto break paragraph if more than two lines", diff --git a/libse/NikseBitmap.cs b/libse/NikseBitmap.cs index ef5a37ae6..e78826e6e 100644 --- a/libse/NikseBitmap.cs +++ b/libse/NikseBitmap.cs @@ -966,7 +966,7 @@ namespace Nikse.SubtitleEdit.Core /// Returns brightest color (not white though) /// /// Brightest color, if not found or if brightes color is white, then Color.Transparent is returned - public Color GetBrightestColor() + public Color GetBrightestColorWhiteIsTransparent() { int max = Width * Height - 4; Color brightest = Color.Black; @@ -983,6 +983,23 @@ namespace Nikse.SubtitleEdit.Core return brightest; } + /// + /// Returns brightest color + /// + /// Brightest color + public Color GetBrightestColor() + { + int max = Width * Height - 4; + Color brightest = Color.Black; + for (int i = 0; i < max; i++) + { + Color c = GetPixelNext(); + if (c.A > 220 && c.R + c.G + c.B > 200 && c.R + c.G + c.B > brightest.R + brightest.G + brightest.B) + brightest = c; + } + return brightest; + } + private static bool IsColorClose(Color color1, Color color2, int maxDiff) { if (Math.Abs(color1.R - color2.R) < maxDiff && Math.Abs(color1.G - color2.G) < maxDiff && Math.Abs(color1.B - color2.B) < maxDiff) diff --git a/libse/TransportStream/TransportStreamParser.cs b/libse/TransportStream/TransportStreamParser.cs index 0112e161a..5be21b002 100644 --- a/libse/TransportStream/TransportStreamParser.cs +++ b/libse/TransportStream/TransportStreamParser.cs @@ -40,6 +40,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream /// Can be used with e.g. MemoryStream or FileStream /// /// Input stream + /// Optional callback event to follow progress public void Parse(Stream ms, LoadTransportStreamCallback callback) { bool firstVideoPtsFound = false; @@ -265,7 +266,8 @@ namespace Nikse.SubtitleEdit.Core.TransportStream foreach (int pid in SubtitlePacketIds) { var subtitles = new List(); - var list = GetSubtitlePesPackets(pid); + var list = ParseAndRemoveEmpty(GetSubtitlePesPackets(pid)); + if (list != null) { for (int i = 0; i < list.Count; i++) @@ -279,7 +281,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream sub.Pes = pes; if (i + 1 < list.Count && list[i + 1].PresentationTimestampToMilliseconds() > 25) sub.EndMilliseconds = list[i + 1].PresentationTimestampToMilliseconds() - 25; - if (sub.EndMilliseconds < sub.StartMilliseconds) + if (sub.EndMilliseconds < sub.StartMilliseconds || sub.EndMilliseconds - sub.StartMilliseconds > (ulong)Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds) sub.EndMilliseconds = sub.StartMilliseconds + 3500; subtitles.Add(sub); if (sub.StartMilliseconds < firstVideoMs) @@ -341,6 +343,20 @@ namespace Nikse.SubtitleEdit.Core.TransportStream return null; } + private List ParseAndRemoveEmpty(List list) + { + var newList = new List(); + foreach (var pes in list) + { + pes.ParseSegments(); + if (pes.ObjectDataList.Count > 0 || pes.PresentationTimestamp > 0) + { + newList.Add(pes); + } + } + return newList; + } + private static void AddPesPacket(List list, List packetList) { int bufferSize = 0; diff --git a/src/Forms/VobSubOcr.cs b/src/Forms/VobSubOcr.cs index 7c54043a5..21e65b06c 100644 --- a/src/Forms/VobSubOcr.cs +++ b/src/Forms/VobSubOcr.cs @@ -238,7 +238,7 @@ namespace Nikse.SubtitleEdit.Forms private Object _modiDoc; private bool _modiEnabled; - private bool _fromMenuItem = false; + private bool _fromMenuItem; // DVD rip/vobsub private List _vobSubMergedPackistOriginal; @@ -308,7 +308,7 @@ namespace Nikse.SubtitleEdit.Forms // optimization vars private int _numericUpDownPixelsIsSpace = 6; private double _numericUpDownMaxErrorPct = 6; - private int _ocrMethodIndex = 0; + private int _ocrMethodIndex; private bool _autoBreakLines = false; private int _ocrMethodTesseract = 0; @@ -1463,7 +1463,7 @@ namespace Nikse.SubtitleEdit.Forms nDvbBmp.CropTopTransparent(2); nDvbBmp.CropTransparentSidesAndBottom(2, true); if (checkBoxTransportStreamGetColorAndSplit.Checked) - _dvbSubColor = nDvbBmp.GetBrightestColor(); + _dvbSubColor = nDvbBmp.GetBrightestColorWhiteIsTransparent(); if (checkBoxAutoTransparentBackground.Checked) nDvbBmp.MakeBackgroundTransparent((int)numericUpDownAutoTransparentAlphaMax.Value); if (checkBoxTransportStreamGrayscale.Checked) @@ -1481,7 +1481,7 @@ namespace Nikse.SubtitleEdit.Forms nDvbBmp.CropTopTransparent(2); nDvbBmp.CropTransparentSidesAndBottom(2, true); if (checkBoxTransportStreamGetColorAndSplit.Checked) - _dvbSubColor = nDvbBmp.GetBrightestColor(); + _dvbSubColor = nDvbBmp.GetBrightestColorWhiteIsTransparent(); if (checkBoxAutoTransparentBackground.Checked) nDvbBmp.MakeBackgroundTransparent((int)numericUpDownAutoTransparentAlphaMax.Value); if (checkBoxTransportStreamGrayscale.Checked) @@ -3041,7 +3041,7 @@ namespace Nikse.SubtitleEdit.Forms if (smallestDifference > 2 && target.Width > 15) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); - int topCrop = 0; + int topCrop; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); if (cutBitmap2.Height != target.Height) FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _compareBitmaps); @@ -8595,16 +8595,44 @@ namespace Nikse.SubtitleEdit.Forms { if (dvbSub.ActiveImageIndex == null) { + var tempList = new List(); for (int i = 0; i < dvbSub.Pes.ObjectDataList.Count; i++) { - var newDbvSub = new TransportStreamSubtitle(); - newDbvSub.Pes = dvbSub.Pes; - newDbvSub.ActiveImageIndex = i; - newDbvSub.StartMilliseconds = dvbSub.StartMilliseconds; - newDbvSub.EndMilliseconds = dvbSub.EndMilliseconds; - if (newDbvSub.Pes.ObjectDataList[i].TopFieldDataBlockLength > 8) - list.Add(newDbvSub); + if (dvbSub.Pes.ObjectDataList[i].TopFieldDataBlockLength > 8) + { + tempList.Add(new TransportStreamSubtitle + { + Pes = dvbSub.Pes, + ActiveImageIndex = i, + StartMilliseconds = dvbSub.StartMilliseconds, + EndMilliseconds = dvbSub.EndMilliseconds + }); + } } + + if (tempList.Count > 1) + { + var lastColor = Color.Transparent; + bool allAlike = true; + foreach (var item in tempList) + { + var dvbBmp = item.GetActiveImage(); + var nDvbBmp = new NikseBitmap(dvbBmp); + var color = nDvbBmp.GetBrightestColor(); + if (lastColor != Color.Transparent && (Math.Abs(color.R - lastColor.R) > 10 || Math.Abs(color.G - lastColor.G) > 10 || Math.Abs(color.B - lastColor.B) > 10)) + { + allAlike = false; + break; + } + lastColor = color; + } + if (allAlike) + { + tempList.Clear(); + tempList.Add(dvbSub); + } + } + list.AddRange(tempList); } else {