Как заставить поток растровых изображений process.standardinput работать в tesseract?

#c# #process #bitmap #tesseract #stdin

#c# #процесс #растровое изображение #tesseract #стандартный файл

Вопрос:

Я пытаюсь захватить часть изображения рабочего стола, а затем запустить его с tesseract.exe без необходимости записывать захваченное изображение на диск в виде файла. Однако следующий код выдает ошибку или процесс не завершается. Помогите, пожалуйста?

 Bitmap bmp=capture_and_crop();
       using (Process process = new Process())
                        {                
                            process.StartInfo.FileName = ts5path "tesseract.exe";
                        process.StartInfo.Arguments = "stdin"   " stdout -l "   language   " --psm "   PSM_setting   " -c preserve_interword_spaces=1";
                                                    process.StartInfo.UseShellExecute = false;
                            process.StartInfo.RedirectStandardInput = true;
                            process.StartInfo.RedirectStandardOutput = true;
                            process.StartInfo.RedirectStandardError = true;
                            process.StartInfo.CreateNoWindow = true;
                            process.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
        
                            process.Start();
                            
                            BinaryWriter writer = new BinaryWriter(process.StandardInput.BaseStream);//line1. I get error here : standardIn has not been redirected, when I move these 2 lines above process.Start().
                            bmp.Save(writer.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp);//line2.
    //If these lines stay here there will be no redirection exception but this process will never end...
        
                            StreamReader reader = process.StandardOutput;
                            string output = reader.ReadToEnd();
                            addtr1.str = output;
                        
                        process.WaitForExit();
                        }
  

Комментарии:

1. Ваша проблема заключается в обнаружении, когда процесс завершается. WaitForExit не станет истинным, пока процесс не закроется. Возвращает ли приложение результат? ReadToEnd должен быть в цикле, потому что он возвращается немедленно. Вы читаете поток, и ReadToEnd выполняет чтение до конца потока. Если приложение завершается возвратом, вместо этого вы можете использовать ReadLine(). Если приложение остается открытым, то WaitForExit следует исключить, тогда код должен работать, если только приложение не возвращает значение StandardOutput (приложение может иметь ‘ 0’ вместо значения return).

2. Если я не использую stdIn, то этот код работает идеально. Однако это означает, что я должен сохранить файл изображения на диск, а затем использовать его вместо stdin. Вопрос в том, как мне заставить его работать со стандартным интерфейсом.

3. При сохранении в файл Windows закрывает поток, поэтому все работает нормально. Вы записываете данные правильно, а затем зависаете, потому что не определяете, когда приложение завершается.

4. Я удалил WaitForExit и изменил ReadToEnd на ReadLine (), но программа по-прежнему зависает. Затем, когда я перемещаю часть записи BinaryWriter в вышеупомянутый process.start, это вызывает ‘System. Исключение InvalidOperationException: StandardIn не был перенаправлен.’

5. Вы должны посмотреть на ответ и увидеть конечный символ (ы). Это может быть значение null или вместо возвращаемого Windows ‘ n’ может быть просто ‘ r’.

Ответ №1:

 BinaryWriter writer = new BinaryWriter(process.StandardInput.BaseStream);                                        
                    bmp.Save(writer.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp);
    process.StandardInput.BaseStream.Close();
  

Большое спасибо jdweng. процесс.Стандартный ввод.Базовый поток.Close(); был необходим сразу после того, как bitmap был записан в базовый поток stdin, чтобы закрыть поток, чтобы ReadToEnd мог закрыться, и программа могла двигаться дальше.