public static OcrOutputFormat GetDocumentFormatFromExt(string documentPath)
        {
            OcrOutputFormat sourceDocumentFormat = OcrOutputFormat.None;

            if (!string.IsNullOrWhiteSpace(documentPath))
            {
                string ext = Path.GetExtension(documentPath);
                if (ext.ToLower().Contains("pdf"))
                {
                    sourceDocumentFormat = OcrOutputFormat.Pdf;
                }
                else if (ext.ToLower().Contains("doc"))
                {
                    sourceDocumentFormat = OcrOutputFormat.Docx;
                }
                else if (ext.ToLower().Contains("rtf"))
                {
                    sourceDocumentFormat = OcrOutputFormat.Rtf;
                }
                else if (ext.ToLower().Contains("svg"))
                {
                    sourceDocumentFormat = OcrOutputFormat.Svg;
                }
                else if (ext.ToLower().Contains("txt"))
                {
                    sourceDocumentFormat = OcrOutputFormat.Text;
                }
            }

            return(sourceDocumentFormat);
        }
        private string GetOutputDocumentFilePath(LEADDocument document, OcrOutputFormat outputFormat)
        {
            if (string.IsNullOrWhiteSpace(_documentsDirectory))
            {
                if (document.GetCache() != null)
                {
                    _documentsDirectory = (document.GetCache() as FileCache).CacheDirectory;
                }
                else
                {
                    _documentsDirectory = Path.Combine(_applicationDirectory, "Cache");
                    if (!Directory.Exists(Path.GetDirectoryName(_documentsDirectory)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(_documentsDirectory));
                    }
                }
            }

            string tempFilesDirectory = Path.Combine(_applicationDirectory, "Temp");

            if (!Directory.Exists(Path.GetDirectoryName(tempFilesDirectory)))
            {
                Directory.Delete(tempFilesDirectory, true);
            }

            Directory.CreateDirectory(tempFilesDirectory);

            // Remove extension from document name (if any)
            string documentName           = Path.GetFileNameWithoutExtension(document.Name);
            string outputDocumentFilePath = Path.Combine(tempFilesDirectory, documentName + outputFormat.GetFormatExtention());

            return(outputDocumentFilePath);
        }
        private async void ShowDocumentConverterPage(OcrOutputFormat outputFormat)
        {
            bool shouldBurnAnnotations = false;

            if (_shareAfterConversion && (IsPdfFormat(SourceDocumentFormat) || IsPdfFormat(outputFormat)) && HasAnnotations)
            {
                // If we have annotation objects drawn and user would like to share his document then show message box asking him/her
                // if they would like to burn the annotations.
                shouldBurnAnnotations = await DisplayAlert("Burn Annotations", "Would you like to burn the drawn annotations into the shared document?", "Yes", "No");
            }

            _annotationsMode = shouldBurnAnnotations ? DocumentConverterAnnotationsMode.Overlay : DocumentConverterAnnotationsMode.External;
            DocumentConverterPage documentConverterPage = new DocumentConverterPage(
                _documentViewer,
                _applicationDirectory,
                _documentsDirectory,
                new List <string> {
                _documentViewer.Document.DocumentId
            },
                _documentConverterHelper,
                outputFormat,
                _annotationsMode);

            documentConverterPage.PageClosing += DocumentConverterPage_PageClosing;
            await PopupNavigation.Instance.PushAsync(documentConverterPage);
        }
 private bool IsPdfFormat(OcrOutputFormat format)
 {
     return(
         format == OcrOutputFormat.Pdf ||
         format == OcrOutputFormat.PdfA ||
         format == OcrOutputFormat.PdfAImageOverText ||
         format == OcrOutputFormat.PdfEmbeddedFonts ||
         format == OcrOutputFormat.PdfImageOverText ||
         format == OcrOutputFormat.PdfImageOverTextEmbeddedFonts);
 }
        public OcrSettingsPage(IOcrEngine ocrEngine)
        {
            _ocrEngine     = ocrEngine;
            BindingContext = this;
            InitializeComponent();
            AfterInitializeComponent();

            // Handle converter options
            LanguagesLabel.Text     = ReadableActiveLanguages(ActiveLanguages);
            OutputFormatLabel.Text  = OcrOutputFormat.GetFormatName();
            TitleExtraButtonTapped += AboutButton_TitleExtraButtonTapped;
        }
        public DocumentViewerPage(string appDirectory,
                                  string documentsDirectory,
                                  LEADDocument document,
                                  ObservableCollection <DocumentItemData> documents,
                                  OcrOutputFormat sourceDocumentFormat,
                                  OcrOutputFormat outputDocumentFormat,
                                  int documentIndexInList,
                                  DocumentConverterHelper documentConverterHelper,
                                  DocumentScanType scanType,
                                  string pageTitle,
                                  string pageLanguage,
                                  bool allowConversionInsideDocumentViewerPage)
        {
            MessagingCenter.Subscribe <object, string>(this, "OnSleep", (sender, parameter) =>
            {
                CancelSpeech();
            });

            _documents           = documents;
            _documentIndexInList = documentIndexInList;
            _pageLanguage        = !string.IsNullOrWhiteSpace(pageLanguage) ? pageLanguage : "en";

            _applicationDirectory    = appDirectory;
            _documentsDirectory      = documentsDirectory;
            _documentConverterHelper = documentConverterHelper;
            SourceDocumentFormat     = sourceDocumentFormat;
            OutputDocumentFormat     = outputDocumentFormat;
            AllowConversionInsideDocumentViewerPage = allowConversionInsideDocumentViewerPage;

            _cts = new CancellationTokenSource();

            InitializeComponent();

            if (Device.RuntimePlatform == Device.iOS)
            {
                HasSystemPadding = false;
            }

            // Set thumbnails and annotations layouts heights and margins
            double bottomMargin            = DemoUtilities.Instance.SafeAreaBottom;
            double thumbnailsLayoutHeight  = DemoUtilities.DisplayHeight * 0.7 - bottomMargin;
            double annotationsLayoutHeight = DemoUtilities.DisplayHeight * 0.5 - bottomMargin;

            ThumbnailsLayout.Margin        = new Thickness(0, 0, 0, bottomMargin);
            ThumbnailsLayout.HeightRequest = thumbnailsLayoutHeight;

            AnnotationsLayout.Margin        = new Thickness(0, 0, 0, bottomMargin);
            AnnotationsLayout.HeightRequest = annotationsLayoutHeight;

            InitDocumentViewer(scanType);
            SetDocument(document);
            SetupUI(scanType, pageTitle);
        }
        public OcrFormatsPage(OcrOutputFormat ocrOutputFormat, bool fullScreenMode = true, bool closePageAfterSelectingOutputFormat = false, bool showFormatsListOnly = false, double topMargin = -1, int cornersRadius = 0)
            : base(!fullScreenMode, LayoutAlignment.Start, showFormatsListOnly, topMargin, cornersRadius)
        {
            InitializeComponent();

            _closePageAfterSelectingOutputFormat = closePageAfterSelectingOutputFormat;

            // Setup the list view
            Formats = ((OcrOutputFormat[])Enum.GetValues(typeof(OcrOutputFormat))).Where(format => format != OcrOutputFormat.None).Select(format => new OutputFormatObject(format)).ToArray();
            FormatListView.ItemsSource = Formats;

            // Rrestore selection
            for (int i = 0; i < Formats.Length; i++)
            {
                if (Formats[i].OcrOutputFormat == ocrOutputFormat)
                {
                    // Select
                    _SelectedIndex = i;

                    // Ensure visible
                    if (Device.RuntimePlatform != Device.UWP)
                    {
                        // For some reason this line crashes UWP in Release mode only so don't execute it for UWP
                        FormatListView.ScrollTo(Formats[i], ScrollToPosition.MakeVisible, false);
                    }
                    break;
                }
            }

            // Default to first item
            if (_SelectedIndex < 0)
            {
                _SelectedIndex = 0;
            }

            Formats[_SelectedIndex].IsSelected = true;
        }
        private async void ConvertDocuments(List <string> documentsIds, OcrOutputFormat outputFormat)
        {
            ConversionData conversionData = null;

            _documentConverterHelper.JobOperation += Converter_JobOperation;

            DocumentConverterJobStatus status = DocumentConverterJobStatus.Success;
            Dictionary <string, DocumentConvertResult> results = new Dictionary <string, DocumentConvertResult>();

            foreach (var documentId in documentsIds)
            {
                try
                {
                    LEADDocument document = LEADDocumentHelper.LoadFromCache(documentId);
                    if (document == null)
                    {
                        results.Add(documentId, new DocumentConvertResult(null, DocumentConverterJobStatus.SuccessWithErrors, new Exception($"Unable to load document with ID {documentId} from cache")));
                        continue;
                    }

                    string outputDocumentPath = GetOutputDocumentFilePath(document, outputFormat);
                    conversionData = new ConversionData()
                    {
                        Document                  = document,
                        DocumentViewer            = _documentViewer,
                        FirstPageIndex            = 0,
                        LastPageIndex             = -1,
                        OutputFormat              = outputFormat,
                        OutputDocumentPath        = outputDocumentPath,
                        OutputAnnotationsFileName = Path.ChangeExtension(outputDocumentPath, "xml"),
                        AnnotationsMode           = _annotationsMode,
                        Zones            = null,
                        DocumentScanType = DocumentScanType.Document
                    };

                    status = _documentConverterHelper.Run(conversionData);
                    if (_abort)
                    {
                        status = DocumentConverterJobStatus.Aborted;
                    }

                    List <string> finalOutputDocumentFiles = new List <string>();
                    if (_annotationsMode == DocumentConverterAnnotationsMode.External)
                    {
                        string firstDocumentFilePath = string.Empty;
                        foreach (string file in _documentConverterHelper.OutputDocumentFiles)
                        {
                            if (File.Exists(file))
                            {
                                if (string.IsNullOrWhiteSpace(firstDocumentFilePath))
                                {
                                    firstDocumentFilePath = file;
                                }
                                string outputDocumentFilePath = Path.Combine(_documentsDirectory, Path.GetFileName(file));
                                if (File.Exists(outputDocumentFilePath))
                                {
                                    File.Delete(outputDocumentFilePath);
                                }

                                File.Move(file, outputDocumentFilePath);
                                finalOutputDocumentFiles.Add(outputDocumentFilePath);
                            }
                        }

                        if (!string.IsNullOrWhiteSpace(firstDocumentFilePath))
                        {
                            // Move annotations file to documents directory
                            string tempAnnotationsFilePath = Path.Combine(Path.GetDirectoryName(firstDocumentFilePath), $"{document.Name}.xml");
                            if (File.Exists(tempAnnotationsFilePath))
                            {
                                string outputAnnotationsFilePath = Path.Combine(_documentsDirectory, Path.ChangeExtension(Path.GetFileName(tempAnnotationsFilePath), "xml"));
                                if (File.Exists(outputAnnotationsFilePath))
                                {
                                    File.Delete(outputAnnotationsFilePath);
                                }

                                File.Move(tempAnnotationsFilePath, outputAnnotationsFilePath);
                            }
                        }
                    }
                    else if (_documentConverterHelper.OutputDocumentFiles.Count > 0)
                    {
                        // In case of burning annotation into PDF file, which only occurs when sharing the document while it has annotations objects drawn
                        // don't move the saved temp file into the final documents directory, share the document from the temp folder
                        finalOutputDocumentFiles.Add(_documentConverterHelper.OutputDocumentFiles[0]);
                    }

                    results.Add(documentId, new DocumentConvertResult(finalOutputDocumentFiles, status, _documentConverterHelper.Error));

                    if (_abort)
                    {
                        List <string> convertedFiles = new List <string>();
                        foreach (KeyValuePair <string, DocumentConvertResult> entry in results)
                        {
                            if (entry.Value.OutputDocumentFiles != null && entry.Value.OutputDocumentFiles.Count > 0)
                            {
                                convertedFiles.AddRange(entry.Value.OutputDocumentFiles);
                            }
                        }

                        DocumentConverterHelper.DeleteAllFiles(convertedFiles);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    results.Add(documentId, new DocumentConvertResult(null, DocumentConverterJobStatus.SuccessWithErrors, ex));
                }
            }

            _documentConverterHelper.JobOperation -= Converter_JobOperation;

            // Go back
            _pageClosingEventArgs = new DocumentConvertEventArgs(results, status, outputFormat);
            await PopupNavigation.Instance.PopAsync();
        }
        public DocumentConverterPage(DocumentViewer documentViewer, string appDirectory, string documentsDirectory, List <string> documentsIds, DocumentConverterHelper documentConverterHelper, OcrOutputFormat outputFormat, DocumentConverterAnnotationsMode annotationsMode)
        {
            InitializeComponent();

            _documentViewer          = documentViewer;
            _applicationDirectory    = appDirectory;
            _documentsDirectory      = documentsDirectory;
            _documentConverterHelper = documentConverterHelper;
            DocumentsIds             = documentsIds;
            _annotationsMode         = annotationsMode;

            Disappearing += DocumentConverterPage_Disappearing;

            if (Device.RuntimePlatform == Device.iOS)
            {
                HasSystemPadding = false;
            }

            Task.Factory.StartNew(() => ConvertDocuments(documentsIds, outputFormat));
        }
 public DocumentConvertEventArgs(Dictionary <string, DocumentConvertResult> results, DocumentConverterJobStatus status, OcrOutputFormat outputFormat)
 {
     Results      = results;
     Status       = status;
     OutputFormat = outputFormat;
 }
 public SelectedFormatChangedEventArgs(OcrOutputFormat ocrOutputFormat)
 {
     OcrOutputFormat = ocrOutputFormat;
 }
 public OutputFormatObject(OcrOutputFormat format)
 {
     OcrOutputFormat = format;
     Text            = OcrOutputFormat.GetDescription();
 }
 public DocumentFormatItem(OcrOutputFormat documentFormat)
 {
     OutputDocumentFormat = documentFormat;
 }
        public static LEADDocument ReplaceDocument(string oldDocumentID, List <string> newDocumentFiles, ObservableCollection <DocumentItemData> documentsCollection, int oldDocumentIndex, out Exception error)
        {
            error = null;
            var items = documentsCollection.Where(x => x.DocumentId.Equals(oldDocumentID));

            if (items == null || items.Count() == 0)
            {
                error = new Exception($"No document found with ID {oldDocumentID}");
                return(null);
            }

            DocumentItemData oldItemData = items.ElementAt(0);

            DateTime        oldDocumentDate    = oldItemData.Date;
            string          oldDocumentTitle   = oldItemData.Title;
            bool            oldIsSelectedState = oldItemData.IsSelected;
            OcrOutputFormat oldDocumentFormat  = oldItemData.DocumentFormat;

            List <Exception> errors            = null;
            LEADDocument     convertedDocument = CreateDocument(newDocumentFiles, null, null, out errors);

            if (convertedDocument != null && File.Exists(newDocumentFiles[0]))
            {
                OcrOutputFormat format = GetDocumentFormatFromExt(newDocumentFiles[0]);
                SaveDocument(convertedDocument, documentsCollection, format, oldDocumentIndex);

                items = documentsCollection.Where(x => x.DocumentId.Equals(convertedDocument.DocumentId));
                DocumentItemData newItemData = null;
                if (items != null && items.Count() > 0)
                {
                    newItemData = items.ElementAt(0);
                    // Keep the old item name and date since we are sorting documents by date and we don't want to change the converted item position.
                    newItemData.Date       = oldDocumentDate;
                    newItemData.Title      = oldDocumentTitle;
                    newItemData.IsSelected = oldIsSelectedState;

                    // Update the document files inside the "Documents" folder of this item in order to delete them later when we convert this document to another format.
                    newItemData.DocumentFiles = new List <string>(newDocumentFiles);
                    SerializeDocuments(documentsCollection);
                }

                // Delete the old document from cache and create new LEADDocument out of the converted file and replace the converted item in the documents list.
                DeleteFromCache(oldDocumentID);

                // Delete the old document files that built this document object from the "Documents" folder.
                if (newItemData != null && oldItemData.DocumentFiles != null && oldItemData.DocumentFiles.Count > 0)
                {
                    foreach (string docFile in oldItemData.DocumentFiles)
                    {
                        try
                        {
                            if (!newItemData.DocumentFiles.Contains(docFile) && File.Exists(docFile))
                            {
                                File.Delete(docFile);
                            }
                        }
                        catch (Exception) { }
                    }
                }
            }
            else
            {
                if (errors != null && errors.Count > 0)
                {
                    error = errors[0];
                }
            }

            return(convertedDocument);
        }
        public static void SaveDocument(LEADDocument document, ObservableCollection <DocumentItemData> documentsCollection, OcrOutputFormat format = OcrOutputFormat.None, int replaceItemAtIndex = -1, bool autoSerializeDocuments = true)
        {
            string thumbnailPath = Path.Combine(CacheDirectory, document.DocumentId, $"thumbnail.jpeg");

            // Create new document item data
            DateTime currentDatetime = DateTime.Now;

            if (string.IsNullOrWhiteSpace(document.Name))
            {
                if (replaceItemAtIndex == -1) // we are adding new document and not replacing existing one, so use the old document name
                {
                    document.Name = FindUniqueDocumentName(documentsCollection);
                }
                else
                {
                    document.Name = documentsCollection[replaceItemAtIndex].Title;
                }
            }

            string annotationsFilePath = Path.Combine(ApplicationDirectory, "Documents", $"{document.Name}.xml");

            DocumentItemData newDocumentItemData = new DocumentItemData();

            newDocumentItemData.DocumentId            = document.DocumentId;
            newDocumentItemData.DocumentThumbnailPath = thumbnailPath;
            newDocumentItemData.AnnotationsFilePath   = annotationsFilePath;
            newDocumentItemData.Title          = document.Name;
            newDocumentItemData.Date           = currentDatetime;
            newDocumentItemData.DocumentFormat = format;

            if (Device.RuntimePlatform == Device.iOS)
            {
                // Save the original file path that was loaded from gallery, so we can delete it later when we convert this document in
                // order to save space since we won't need this file anymore.
                // only do this for the newly created documents and not the already converted ones.
                if (format == OcrOutputFormat.None)
                {
                    newDocumentItemData.DocumentFiles = GetDocumentSourceFiles(document);
                }
            }

            IEnumerable <DocumentItemData> items = documentsCollection.Where(x => x.DocumentId.Equals(document.DocumentId));

            if ((items != null && items.Count() > 0) || replaceItemAtIndex != -1)
            {
                // Document already exist, so just update it
                int index = (replaceItemAtIndex != -1) ? replaceItemAtIndex : documentsCollection.IndexOf(items.ElementAt(0));
                documentsCollection.Insert(index, newDocumentItemData);
                documentsCollection.RemoveAt(index + 1);
            }
            else
            {
                documentsCollection.Add(newDocumentItemData);
            }

            if (autoSerializeDocuments)
            {
                SerializeDocuments(documentsCollection);
            }

            document.SaveToCache();

            if (document.Pages != null && document.Pages.Count > 0)
            {
                using (var codecs = new RasterCodecs())
                {
                    try
                    {
                        LeadSize thumbnailSize = LeadSize.Create((int)(document.Images.ThumbnailPixelSize.Width * 1.5), (int)(document.Images.ThumbnailPixelSize.Height * 1.5));
                        using (var rasterImage = document.Pages[0].GetImage())
                        {
                            var thumbnailImage = rasterImage.CreateThumbnail(thumbnailSize.Width, thumbnailSize.Height, 32, RasterViewPerspective.TopLeft, RasterSizeFlags.Bicubic);
                            if (thumbnailImage == null)
                            {
                                thumbnailImage = document.Pages[0].GetThumbnailImage();
                            }
                            codecs.Save(thumbnailImage, thumbnailPath, RasterImageFormat.Jpeg, 0);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        codecs.Save(document.Pages[0].GetThumbnailImage(), thumbnailPath, RasterImageFormat.Jpeg, 0);
                    }
                }
            }
        }