PDF JPG
问题
如何从一个pdf
文件中提取图片
思路
分析pdf文件,分析Pdf的文件流内容。pdf内的图片都是jpg格式,所以进一步分析jpg格式文件,然后把bytes数组保存到一个文件即可。
具体做法
- 找到”stream”
- 查看这个stream是否是jpg,在20个字节内寻找十六进制为
0xff, 0xd8
,是jpg文件的开头。 - 如果不是的话继续下一个stream
- 如果是找到”endstream”
- 在endstream位置前20个字节内寻找十六进制为
0xff, 0xd9
,是jpg文件的结尾。 - 把区间的bytes数组保存到文件
- 继续循环寻找下一个stream
- 文件全部找完,退出。
代码
Go 实现
// ExtractPdfImages gets JPG images via parse protocol in pdf stream.
func ExtractPdfImages(pdfname string) ([][]byte, error) {
file, err := os.Open(pdfname)
defer file.Close()
content, err := ioutil.ReadAll(file)
if err != nil { return nil, err }
startLoc, resultImageBytes := 0, make([][]byte, 0)
for {
streamStart := bytesFind(content, []byte("stream"), startLoc)
if streamStart == -1 { break}
jpgStart := bytesFind(content[:streamStart+20], []byte{0xff, 0xd8}, streamStart)
if jpgStart == -1 {
startLoc = streamStart + 20
continue
}
streamEnd := bytesFind(content, []byte("endstream"), jpgStart)
if streamEnd == -1 { return nil, Error{"pdf don't have stream end..."}}
jpgEnd := bytesFind(content, []byte{0xff, 0xd9}, streamEnd - 20)
if jpgEnd == -1 { return nil, Error{"pdf don't have jpg end..."} }
resultImageBytes = append(resultImageBytes, content[jpgStart+1: jpgEnd+1])
if err != nil { return nil, err}
startLoc = jpgEnd
}
return resultImageBytes, nil
}