go-fitz库-PDF文件所有页转换到HTML及从HTML中提取图片的示例教程
本文档将详细介绍如何使用go-fitz库将PDF文件的每一页转换为HTML格式,然后从生成的HTML中提取图片。
1. 准备工作
首先,确保已经安装了go-fitz库:
bash
go get github.com/gen2brain/go-fitz
2. 导入必要的包
go
package main
import (
"fmt" // 用于格式化输出
"log" // 用于记录错误日志
"os" // 用于文件操作
"path/filepath" // 用于处理文件路径
"github.com/gen2brain/go-fitz" // go-fitz库,用于PDF处理
)
3. 创建PDF到HTML转换函数
go
// ConvertPdfToHtml 将PDF文件的每一页转换为HTML并保存到指定目录
// 参数:
// - pdfPath: PDF文件的路径
// - outputDir: 保存HTML文件的目录
// 返回值:
// - error: 错误信息(如果有)
func ConvertPdfToHtml(pdfPath, outputDir string) error {
// 使用fitz.New打开PDF文件,创建文档对象
doc, err := fitz.New(pdfPath)
if err != nil {
return fmt.Errorf("无法打开PDF文件: %v", err)
}
// 使用defer确保在函数结束时关闭文档,释放资源
defer doc.Close()
// 获取PDF文档的总页数
totalPages := doc.NumPage()
fmt.Printf("PDF共%d页,开始转换...\n", totalPages)
// 遍历PDF的每一页,从第0页开始
for i := 0; i < totalPages; i++ {
// 使用doc.HTML方法将第i页转换为HTML格式
// 第一个参数是页码(从0开始),第二个参数为true表示包含图片
html, err := doc.HTML(i, true)
if err != nil {
log.Printf("警告: 转换第%d页失败: %v", i+1, err)
continue
}
// 构造输出文件路径,例如: page_001.html, page_002.html
outputPath := filepath.Join(outputDir, fmt.Sprintf("page_%03d.html", i+1))
// 创建输出文件
outFile, err := os.Create(outputPath)
if err != nil {
log.Printf("警告: 无法创建文件 '%s': %v", outputPath, err)
continue
}
// 将HTML内容写入文件
_, err = outFile.WriteString(html)
if err != nil {
log.Printf("警告: 无法写入文件 '%s': %v", outputPath, err)
outFile.Close()
continue
}
// 关闭文件
outFile.Close()
fmt.Printf("第%d页已保存为: %s\n", i+1, outputPath)
}
fmt.Println("所有页面转换完成!")
return nil
}
4. 从HTML中提取图片的函数
go
// ExtractImagesFromHtml 从HTML文件中提取图片并保存
// 参数:
// - htmlPath: HTML文件的路径
// - outputDir: 保存提取图片的目录
// 返回值:
// - error: 错误信息(如果有)
func ExtractImagesFromHtml(htmlPath, outputDir string) error {
// TODO: 实现从HTML中提取图片的逻辑
// 这里需要使用HTML解析库,如goquery来解析HTML并提取图片
fmt.Printf("从 %s 提取图片到 %s\n", htmlPath, outputDir)
return nil
}
5. 完整的主函数示例
go
func main() {
// 示例使用
pdfFile := "example.pdf" // PDF文件路径
htmlOutputDir := "./html_output" // HTML输出目录
imageOutputDir := "./image_output" // 图片输出目录
// 确保HTML输出目录存在
if err := os.MkdirAll(htmlOutputDir, 0755); err != nil {
log.Fatal("无法创建HTML输出目录:", err)
}
// 确保图片输出目录存在
if err := os.MkdirAll(imageOutputDir, 0755); err != nil {
log.Fatal("无法创建图片输出目录:", err)
}
// 调用转换函数将PDF转换为HTML
if err := ConvertPdfToHtml(pdfFile, htmlOutputDir); err != nil {
log.Fatal("PDF转换失败:", err)
}
// 遍历所有生成的HTML文件并提取图片
err := filepath.Walk(htmlOutputDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 检查是否为HTML文件
if !info.IsDir() && filepath.Ext(path) == ".html" {
fmt.Printf("处理HTML文件: %s\n", path)
// 从HTML文件中提取图片
if err := ExtractImagesFromHtml(path, imageOutputDir); err != nil {
log.Printf("从%s提取图片失败: %v", path, err)
}
}
return nil
})
if err != nil {
log.Fatal("遍历HTML文件失败:", err)
}
fmt.Println("所有操作完成!")
}
6. 更完整的图片提取实现
为了从HTML中提取图片,我们需要使用HTML解析库,如goquery:
bash
go get github.com/PuerkitoBio/goquery
然后实现完整的图片提取功能:
go
import (
"encoding/base64" // 用于解码base64数据
"strings" // 用于字符串处理
"github.com/PuerkitoBio/goquery" // 用于HTML解析
)
// ExtractImagesFromHtml 从HTML文件中提取图片并保存
// 参数:
// - htmlPath: HTML文件的路径
// - outputDir: 保存提取图片的目录
// 返回值:
// - error: 错误信息(如果有)
func ExtractImagesFromHtml(htmlPath, outputDir string) error {
// 使用goquery打开并解析HTML文件
doc, err := goquery.NewDocument(htmlPath)
if err != nil {
return fmt.Errorf("无法解析HTML文件: %v", err)
}
// 计数器,用于生成图片文件名
imageCount := 0
// 查找所有<img>标签
doc.Find("img").Each(func(i int, s *goquery.Selection) {
// 获取图片的src属性
src, exists := s.Attr("src")
if !exists {
return
}
// 增加计数器
imageCount++
// 检查是否为base64编码的图片数据
if strings.HasPrefix(src, "data:image") {
// 提取base64数据部分
parts := strings.Split(src, ",")
if len(parts) != 2 {
log.Printf("无效的base64图片数据: %s", src)
return
}
// 解码base64数据
imgData, err := base64.StdEncoding.DecodeString(parts[1])
if err != nil {
log.Printf("解码base64图片数据失败: %v", err)
return
}
// 确定图片格式
format := "png"
if strings.HasPrefix(parts[0], "data:image/jpeg") {
format = "jpg"
} else if strings.HasPrefix(parts[0], "data:image/gif") {
format = "gif"
}
// 构造输出文件路径
outputPath := filepath.Join(outputDir, fmt.Sprintf("extracted_%03d.%s", imageCount, format))
// 将图片数据写入文件
err = os.WriteFile(outputPath, imgData, 0644)
if err != nil {
log.Printf("保存图片失败: %v", err)
return
}
fmt.Printf("提取图片已保存: %s\n", outputPath)
} else {
// 处理普通图片链接(在PDF转换场景中这种情况较少)
fmt.Printf("发现外部图片链接: %s\n", src)
}
})
fmt.Printf("从 %s 中提取了 %d 张图片\n", htmlPath, imageCount)
return nil
}
7. 总结
通过以上示例,我们学习了如何:
- 使用go-fitz库将PDF文件的每一页转换为HTML格式
- 从生成的HTML文件中提取嵌入的图片
- 处理base64编码的图片数据并保存为文件
这种方法特别适用于需要从PDF中提取图片内容的场景,例如从扫描版PDF中提取条形码、图表等图像信息。go-fitz库基于Poppler库,提供了高质量的PDF转换功能,能够准确地保留PDF中的图像内容。