source: spip-zone/_plugins_/ocr/trunk/inc/ocr_analyser.php @ 75218

Last change on this file since 75218 was 75218, checked in by lesage.sylvain@…, 8 years ago

Stocker les pages d'un PDF sous forme de JSON, au lieu de les concatener

Si un PDF est lié à des images PNG par le plugin doc2img, remplir le
champ ocr du PDF dans le format JSON suivant:
{"1":"texte page 1","3":texte page 3"}
Le texte est en UTF8 dans la base de données, pour permettre l'indexation
des mots.
Dans le cas des documents normaux, ocr contient directement le texte, pas de
format JSON.

File size: 6.1 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) return;
4
5/**
6 * Fonction autonome analysant un document donné en paramètre
7 *
8 *  Ensemble des actions necessaires à l'analyse OCR d'une image
9 *
10 * @param int $id_document identifiant du document à convertir
11 */
12function ocr_analyser($id_document, $dry_run=false) {
13        spip_log('Analyse OCR du document '.$id_document, 'ocr');
14       
15        include_spip('inc/config');
16        $config = lire_config('ocr',array());
17        if ($config['ocr_bin']) {
18                $bin = $config['ocr_bin'];
19        } else {
20                // TODO : essayer de trouver tout seul l'exécutable
21                spip_log('Erreur analyse OCR : Il faut specifier l\'exécutable dans le panneau de configuration');
22                $resultat['info'] = _T('ocr:analyser_erreur_executable_introuvable');
23                $resultat['erreur'] = true;
24                return $resultat;
25        }
26        $opt = $config['ocr_opt'] ? $config['ocr_opt'] : '';
27
28        // Ne retenir que les 50 000 premiers caracteres (ou la valeur choisie)
29        $taille_texte_max = $config['taille_texte_max'] ? $config['taille_texte_max'] : @define('_OCR_TAILLE_TEXTE_MAX',50000);
30       
31        $document = ocr_document($id_document);
32        spip_log($document, 'ocr');
33
34        $fichier = $document['fichier'];
35
36        if (!$fichier) {
37                $resultat['info'] = _T('ocr:analyser_erreur_document_inexistant');
38                $resultat['erreur'] = true;
39                return $resultat;
40        }
41       
42        $dest = $document['cible_url'].$document['basename'];
43       
44        $cmd = $bin.$options.' '.$fichier.' '.$dest.' '.$opt;
45        spip_log('Commande d\'analyse OCR : "'.$cmd.'"', 'ocr');
46        exec($cmd, $output, $status_code);
47        $erreur = ocr_texte_erreur($status_code);
48
49        if ($erreur) {
50                spip_log('Erreur : '.$erreur, 'ocr');
51                $resultat['info'] = $erreur;
52                $resultat['erreur'] = true;
53                sql_updateq("spip_documents", array('ocr_analyse' => 'err'), "id_document=".intval($id_document));
54        } else  {
55                // on ouvre et on lit le .txt
56                // TODO : comment connaitre l'encoding du fichier ?
57                $nouveaufichier = $dest.'.txt';
58                if (file_exists($nouveaufichier) && is_readable($nouveaufichier)) {
59                        $texte = file_get_contents($nouveaufichier);
60                        unlink($nouveaufichier);
61                        $texte = substr($texte, 0, $taille_texte_max);
62                        if ($dry_run) {
63                                $resultat['info'] = $texte;
64                        } else {
65                                // On teste si le document est une image générée par doc2img (mode='doc2img' + présente dans spip_documents_liens, liée avec un objet 'document')
66                                $resultat_sql = sql_fetsel("L1.page, L2.id_objet AS id_document_original","spip_documents as L1 LEFT JOIN spip_documents_liens as L2 ON L1.id_document=L2.id_document","L2.id_document=".intval($id_document).' AND L2.objet="document" AND L1.mode="doc2img"');
67                                if ($resultat_sql) {
68                                        $page = $resultat_sql['page'];
69                                        $id_document_original = $resultat_sql['id_document_original'];
70                                        // Si oui, on colle le texte dans le champ "ocr" du document original (on ne teste pas s'il y a plusieurs documents, ça ne devrait pas)
71                                        // Dans ce cas, le champ "ocr" est un tableau JSON des pages du document
72                                        spip_log('Modification du champ "ocr" du document '.$id_document_original.' (page '.$page.') - c\'est le document original qui avait été converti par doc2img' , 'ocr');
73                                        $ocr_original = sql_getfetsel("ocr","spip_documents","id_document=".intval($id_document_original));
74                                        // Décoder le JSON ou initialiser
75                                        $ocr_array = $ocr_original ? json_decode($ocr_original, true) : array();
76                                        // Ajouter la page
77                                        $ocr_array[$page] = $texte;
78                                        // Coder le JSON
79                                        include_spip('ocr_options');
80                                        $ocr_json = json_encode_utf8($ocr_array);
81                                        // Insérer dans la base
82                                        sql_updateq("spip_documents", array('ocr' => $ocr_json), "id_document=".intval($id_document_original));
83                                        // Indiquer que l'image doc2img a été analysée
84                                        sql_updateq("spip_documents", array('ocr_analyse' => 'oui'), "id_document=".intval($id_document));
85                                } else {
86                                        // sinon, on modifie le champ "ocr" de l'image
87                                        spip_log('Modification du champ "ocr" du document '.$id_document, 'ocr');
88                                        sql_updateq("spip_documents", array('ocr' => $texte, 'ocr_analyse' => 'oui'), "id_document=".intval($id_document));
89                                }
90                        }
91                        $resultat['success'] = true;
92                } else {
93                        $resultat['info'] = _T('ocr:analyser_erreur_fichier_resultat');
94                        $resultat['erreur'] = true;
95                        sql_updateq("spip_documents", array('ocr_analyse' => 'err'), "id_document=".intval($id_document));
96                }
97        }
98       
99        return $resultat;
100}
101
102/**
103 * Fonction pour convertir le status_code de tesseract en texte d'erreur
104 *
105 *  Calcul un tableau :
106 *  - avec informations sur le documents (nom, repertoire, nature)
107 *  - determine les informations des documents finaux (nom, respertoire, extension)
108 *
109 * @param $status_code status code retourné par la commande tesseract
110 * @return $erreur vide si pas d'erreur ou texte d'erreur selon le status code
111 */
112function ocr_texte_erreur($status_code) {
113        switch ($status_code) {
114                case 0:
115                        $erreur = '';
116                        break;
117                case 1:
118                case 2:
119                case 3:
120                        $erreur = _T('ocr:analyser_erreur_'.$status_code);
121                        break;
122                default:
123                        $erreur = _T('ocr:analyser_erreur_autre');
124        }
125        return $erreur;
126}
127
128/**
129 * Fonction pour connaitre les infos fichiers du document
130 *
131 *  Génère un table avec :
132 *  - des informations sur le document (nom, extension, repertoire)
133 *  - des informations pour le document à générer (nom, repertoire)
134 *
135 * @param $id_document identifiant du document
136 * @return $document : liste de données caractérisant le document
137 */
138function ocr_document($id_document) {
139
140    //on recupere l'url du document
141    $fichier = sql_fetsel(
142        'fichier,extension',
143        'spip_documents',
144        'id_document='.intval($id_document)
145    );
146
147    //chemin relatif du fichier
148    include_spip('inc/documents');
149    $fichier_reel = get_spip_doc($fichier['fichier']);
150
151    //url relative du repertoire contenant le fichier , on retire aussi le / en fin
152    $document['fichier'] = $fichier_reel;
153
154    //information sur le nom du fichier
155    $document['extension'] = $fichier['extension'];
156    $document['name'] = basename($fichier_reel);
157    $document['basename'] = basename($document['name'], '.png');
158
159    // url relative du repertoire cible
160    if(!is_dir(_DIR_VAR."cache-ocr")) {
161                //creation du repertoire cible
162        sous_repertoire(_DIR_VAR,"cache-ocr");
163        }
164        $document['cible_url'] = _DIR_VAR."cache-ocr".'/';
165
166    return $document;
167}
Note: See TracBrowser for help on using the repository browser.