> 백엔드 개발 > PHP 튜토리얼 > PHP를 사용하여 문서의 이미지를 구문 분석하는 방법

PHP를 사용하여 문서의 이미지를 구문 분석하는 방법

不言
풀어 주다: 2023-04-02 21:56:01
원래의
1873명이 탐색했습니다.

이 글은 주로 PHP에서 단어를 파싱하고 문서에서 그림을 얻는 것에 대해 소개합니다. 이제 특정 참조 가치가 있습니다. 필요한 친구들이 참조할 수 있습니다.

Background

몇 가지 기능을 작성하고 있었습니다. 얼마 전: 기본 PHP를 사용하여 단어로 된 콘텐츠를 얻고 웹사이트 시스템으로 가져옵니다. 문서에는 수식, 그림, 표 등이 있기 때문에 글쓰기가 더 번거롭습니다.

Idea

일반적인 아이디어는 먼저 Word의 doc 형식의 문서를 docx로 변환하고, 전처리 프로그램을 사용하여 문서의 수식을 swf 이미지 형식으로 변환하고, word를 xml 형식으로 변환한 다음, 콘텐츠는 json 형식으로 변환됩니다.

사전 지식

1. xml의 기본 이해

Xml은 확장 가능한 마크업 언어이며, 프로그래밍 언어와 상관없이 인터넷 플랫폼 전반에 걸쳐 XML을 구현할 수 있습니다. 운영 체제는 인터넷의 최고 수준의 패스를 갖춘 데이터 매체라고 할 수 있습니다.

xml은 구조화된 문서 정보를 처리하는 최신 기술입니다. 서버 간 구조화된 발행을 도와 개발자가 데이터의 저장 및 전송을 보다 편리하게 제어할 수 있습니다.

xml은 전자 문서를 표시하여 구조화된 마크업 언어로 만듭니다. 데이터를 표시하고 데이터 유형을 정의하는 데 사용할 수 있는 마크업 언어를 사용자가 직접 정의할 수 있는 소스 언어입니다. 이는 표준 범용 언어의 하위 집합이며 웹 전송에 매우 적합합니다.

2. 워드 문서의 두 가지 저장 방법

워드 문서의 두 가지 저장 형식: doc 및 docx

doc: 관습적으로 워드라고 하며, 데이터를 저장하기 위해 바이너리를 사용합니다.

docx: 즉, Word2007은 xml을 사용하여 저장합니다. data

그럼 접미사는 당연히 docx 형식인데 왜 xml 형식인가요?

test.docx를 선택하고 접미사 이름을 .zip으로 변경한 후 압축을 풀어 다음 디렉터리 구조를 얻습니다.

그래서 여러분이 생각하는 docx 문서는 실제로 압축 파일입니다~

3. DOM 및 PHP 이해하기 DOM XML 구문 분석

DOM은 html 및 xml 문서에 대한 표준 개체 세트는 물론 이러한 문서에 액세스하고 조작하기 위한 표준 인터페이스를 제공합니다. XML DOM은 문서의 표준을 정의하는 개체 집합입니다. PHP DOM 확장을 사용하면 PHP로 DOM 트리에 일련의 작업을 구현할 수 있습니다.

PHP DOM을 사용하여 XML 문서 읽기:

test.xml:

<?xml version="1.0" encoding="utf-8"?><teststore><test>
    <name>php dom test</name>
    <author>test-one</author></test><test>
    <title>php dom test 2</title>
    <author>test-two</author></test></teststore>
로그인 후 복사

test.php:

<?php    $doc = new DOMDocument();    
$doc->load("test.xml");    //获取标签对象
    $book=$doc->getElementsByTagName("test");    //输出第一个中的值
    echo $book->item(0)->nodeValue;    
    echo "<br>----------------<br>";    
    $title=$doc->getElementsByTagName("name");    
    echo $title->item(0)->nodeValue;    
    echo "<br>----------------<br>";    //遍历所有book标签中的内容
    foreach ($book as $note)
    {        
    echo $note->nodeValue;        
    echo "<br>";
    }
로그인 후 복사

결과:

4 xml의 정의 형식은 단어

입니다. word 데이터는 어떻게 정의되나요? ?

두 개의 파일/폴더만 소개하겠습니다:

한 파일은 전체 단어 문서의 내용을 정의하는 word/document.xml입니다.

또 다른 폴더는 word/media입니다. 이 폴더에는 문서의 멀티미디어 콘텐츠가 저장됩니다. 즉, 문서의 모든 사진, 오디오 및 비디오가 이 폴더에 저장됩니다.

document.ml의 전체 구조 정의:

<w:document mc:ignorable="w14 w15 wp14" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpscustomdata="http://www.wps.cn/officeDocument/2013/wpsCustomData">
    <w:body>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="2">
                </w:pstyle>
                <w:keepnext w:val="0">
                </w:keepnext>
                <w:keeplines w:val="0">
                </w:keeplines>
                <w:widowcontrol>
                </w:widowcontrol>
                <w:suppresslinenumbers w:val="0">
                </w:suppresslinenumbers>
                <w:pbdr>
                    <w:top w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:top>
                    <w:left w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:left>
                    <w:bottom w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:bottom>
                    <w:right w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:right>
                </w:pbdr>
로그인 후 복사

문서 단락 내용:

<w:p>
            <w:ppr>
                <w:pstyle w:val="2">
                </w:pstyle>
                <w:keepnext w:val="0">
                </w:keepnext>
                <w:keeplines w:val="0">
                </w:keeplines>
                <w:widowcontrol>
                </w:widowcontrol>
                <w:suppresslinenumbers w:val="0">
                </w:suppresslinenumbers>
                <w:pbdr>
                    <w:top w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:top>
                    <w:left w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:left>
                    <w:bottom w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:bottom>
                    <w:right w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:right>
                </w:pbdr>
                <w:shd w:fill="FAFAFA" w:val="clear">
                </w:shd>
                <w:spacing w:after="150" w:afterautospacing="0" w:before="150" w:beforeautospacing="0" w:line="378" w:linerule="atLeast">
                </w:spacing>
                <w:ind w:firstline="0" w:left="0" w:right="0">
                </w:ind>
                <w:rpr>
                    <w:rfonts w:ascii="Verdana" w:cs="Verdana" w:hansi="Verdana" w:hint="default">
                    </w:rfonts>
                    <w:i w:val="0">
                    </w:i>
                    <w:caps w:val="0">
                    </w:caps>
                    <w:color w:val="404040">
                    </w:color>
                    <w:spacing w:val="0">
                    </w:spacing>
                    <w:sz w:val="21">
                    </w:sz>
                    <w:szcs w:val="21">
                    </w:szcs>
                </w:rpr>
            </w:ppr>
            <w:r>
                <w:rpr>
                    <w:rfonts w:ascii="Verdana" w:cs="Verdana" w:hansi="Verdana" w:hint="default">
                    </w:rfonts>
                    <w:i w:val="0">
                    </w:i>
                    <w:caps w:val="0">
                    </w:caps>
                    <w:color w:val="404040">
                    </w:color>
                    <w:spacing w:val="0">
                    </w:spacing>
                    <w:sz w:val="21">
                    </w:sz>
                    <w:szcs w:val="21">
                    </w:szcs>
                    <w:bdr w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:bdr>
                    <w:shd w:fill="FAFAFA" w:val="clear">
                    </w:shd>
                </w:rpr>
                <w:t>
                    作者: Test                </w:t>
            </w:r>
        </w:p>
로그인 후 복사

이미지 내용 정의:

<w:r>
                <w:rpr>
                    <w:rfonts w:ascii="Verdana" w:cs="Verdana" w:hansi="Verdana" w:hint="default">
                    </w:rfonts>
                    <w:i w:val="0">
                    </w:i>
                    <w:caps w:val="0">
                    </w:caps>
                    <w:color w:val="404040">
                    </w:color>
                    <w:spacing w:val="0">
                    </w:spacing>
                    <w:sz w:val="21">
                    </w:sz>
                    <w:szcs w:val="21">
                    </w:szcs>
                    <w:bdr w:color="auto" w:space="0" w:sz="0" w:val="none">
                    </w:bdr>
                    <w:shd w:fill="FAFAFA" w:val="clear">
                    </w:shd>
                </w:rpr>
                <w:drawing>
                    <wp:inline distb="0" distl="114300" distr="114300" distt="0">
                        <wp:extent cx="5543550" cy="5543550">
                        </wp:extent>
                        <wp:effectextent b="0" l="0" r="0" t="0">
                        </wp:effectextent>
                        <wp:docpr descr="IMG_256" id="1" name="Picture 1">
                        </wp:docpr>
                        <wp:cnvgraphicframepr>
                            <a:graphicframelocks nochangeaspect="1" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
                            </a:graphicframelocks>
                        </wp:cnvgraphicframepr>
                        <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
                            <a:graphicdata uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                                <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                                    <pic:nvpicpr>
                                        <pic:cnvpr descr="IMG_256" id="1" name="Picture 1">
                                        </pic:cnvpr>
                                        <pic:cnvpicpr>
                                            <a:piclocks nochangeaspect="1">
                                            </a:piclocks>
                                        </pic:cnvpicpr>
                                    </pic:nvpicpr>
                                    <pic:blipfill>
                                        <a:blip r:embed="rId4">
                                        </a:blip>
                                        <a:stretch>
                                            <a:fillrect>
                                            </a:fillrect>
                                        </a:stretch>
                                    </pic:blipfill>
                                    <pic:sppr>
                                        <a:xfrm>
                                            <a:off x="0" y="0">
                                            </a:off>
                                            <a:ext cx="5543550" cy="5543550">
                                            </a:ext>
                                        </a:xfrm>
                                        <a:prstgeom prst="rect">
                                            <a:avlst>
                                            </a:avlst>
                                        </a:prstgeom>
                                        <a:nofill>
                                        </a:nofill>
                                        <a:ln w="9525">
                                            <a:nofill>
                                            </a:nofill>
                                        </a:ln>
                                    </pic:sppr>
                                </pic:pic>
                            </a:graphicdata>
                        </a:graphic>
                    </wp:inline>
                </w:drawing>
            </w:r>
로그인 후 복사

결론:

<w:document>  定义整个文档的开始    
<w:body>    document的子节点,文档的主体内容        
<w:p>    body的子节点,一个段落,就是word文档中的段落           
<w:r>    p元素的子节点,一个Run定义了段落中具有相同格式的一段内容                
<w:t>    Run元素节点的子节点,就是文档的内容                
<w:drawing>    run元素的子节点,定义了一张图片                    
<w:inline>    drawing子节点,具体应用没有研究                    
<a:graphic>     定义了图片内容                        
<pic:blipfill>    graphic文档的子节点,定义了图片内容的索引.
로그인 후 복사

특히 Java를 사용하는 경우 XWPF는 docx 문서를 다음과 같이 구문 분석합니다. XML 문서 구문 분석을 수행하고 모든 노드를 얻은 다음 이를 보다 유용한 속성으로 변환하여 사용할 API를 제공합니다. Java에서 POI는 이 이름을 기반으로 이미지에 해당하는 리소스를 얻을 수 있으며 이미지 위치를 얻는 키는 여기에 있습니다. .

하지만 아쉽게도 저는 php를 사용하고 있습니다~~그래서 php의 관련 인터페이스를 통해 이미지 획득을 수동으로 구현해야 합니다.

구체적인 아이디어에 대해 이야기하겠습니다. PHP에 내장된 DOMDocument 인터페이스는 docx 문서의 xml 노드를 획득하고 xml 노드를 탐색하여 이미지를 저장하는 노드 요소를 찾은 다음 이미지 노드를 탐색하여 r:embed 인덱스 값까지 이동합니다. docx 문서는 압축된 패키지 형식이기 때문에 docx 문서는 PHP 내장 인터페이스 ZipArchive 인터페이스를 통해 탐색되고(본질적으로 .zip 압축 패키지 탐색) 해당 이미지는 인덱스를 통해 찾아 바이너리 데이터로 변환되며, 그런 다음 img 태그 표시 형식으로 접합한 것은 base64 이미지 데이터입니다.

xml로 변환:

   private $rels_xml;
    private $doc_xml;
    
    private function readZipPart($filename) {
        $zip = new ZipArchive();
        $_xml = &#39;word/document.xml&#39;;
        $_xml_rels = &#39;word/_rels/document.xml.rels&#39;;
        if (true === $zip->open($filename)) {
            if (($index = $zip->locateName($_xml)) !== false) {
                $xml = $zip->getFromIndex($index);
            }
            $zip->close();
        } else die(&#39;non zip file&#39;);
        
        if (true === $zip->open($filename)) {
            if (($index = $zip->locateName($_xml_rels)) !== false) {
                $xml_rels = $zip->getFromIndex($index);                    
            }
            $zip->close();
        } else die(&#39;non zip file&#39;);
        
        $this->doc_xml = new DOMDocument();
        $this->doc_xml->encoding = mb_detect_encoding($xml);
        $this->doc_xml->preserveWhiteSpace = false;
        $this->doc_xml->formatOutput = true;
        $this->doc_xml->loadXML($xml);
        $this->doc_xml->saveXML();
        
        $this->rels_xml = new DOMDocument();
        $this->rels_xml->encoding = mb_detect_encoding($xml);
        $this->rels_xml->preserveWhiteSpace = false;
        $this->rels_xml->formatOutput = true;
        $this->rels_xml->loadXML($xml_rels);
        $this->rels_xml->saveXML();
        
    }
로그인 후 복사

사진 노드인지 확인:

if($paragraph->name === &#39;w:drawing&#39;) {
    (strstr($ts,&#39;…封…&#39;) != false || strstr($ts,&#39;…线…&#39;) != false) ? $t .= &#39;&#39; : $t .= $this->analysisDrawing($paragraph);
}
로그인 후 복사

사진 인덱스 가져오기:

   private function analysisDrawing(&$drawingXml) {
        while($drawingXml->read()) {
            if ($drawingXml->nodeType == XMLREADER::ELEMENT && $drawingXml->name === &#39;a:blip&#39;) {
                $rId = $drawingXml->getAttribute(&#39;r:embed&#39;);
                $rIdIndex = substr($rId,3);
                return $this->checkImageFormating($rIdIndex);
            }
        }
    }
로그인 후 복사

압축된 패키지에 있는 사진 파일 표시:

   private function checkImageFormating($rIdIndex) {

        $imgname = &#39;word/media/image&#39;.($rIdIndex-8);
        $zipfileName =  __DIR__.DIRECTORY_SEPARATOR.&#39;b&#39;.DIRECTORY_SEPARATOR.&#39;test.docx&#39;;
        $zip=zip_open($zipfileName);
        while($zip_entry = zip_read($zip)) {//读依次读取包中的文件
            $file_name=zip_entry_name($zip_entry);//获取zip中的文件名
            if(strstr($file_name,$imgname) != &#39;&#39; ) {
                $a = ($rIdIndex-8 < 10) ? mb_substr($file_name,mb_strlen($imgname,"utf-8"),1, &#39;utf-8&#39;) : &#39;&#39;;    
                if($rIdIndex-8 < 10 && $a != &#39;.&#39;) continue;
                if ($enter_zp = zip_entry_open($zip, $zip_entry, "r")) {  //读取包中文件
                    $ext = pathinfo(zip_entry_name ($zip_entry),PATHINFO_EXTENSION);//获取图片文件扩展名
                    $content = zip_entry_read($zip_entry,zip_entry_filesize($zip_entry));//读取文件二进制数据
                    return sprintf(&#39;<img src="data:image/%s;base64,%s">&#39;, $ext, base64_encode($content));//利用base64_encode函数转换读取到的二进制数据并输入输出到页面中
                }
                zip_entry_close($zip_entry); //关闭zip中打开的项目 
            }
        }
        zip_close($zip);//关闭zip文件   
    }
로그인 후 복사

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

如何用php获取当前页面文件名

 php中heredoc的用法

위 내용은 PHP를 사용하여 문서의 이미지를 구문 분석하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿