You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Go语言将图片转换为PDF文档?——网站图片下载自动转PDF工具开发疑问

Hey there! I totally get the frustration—finding clear docs for batch image-to-PDF in Go can be tricky, especially when most libraries seem focused on the reverse. Since Python was too slow for your use case, let's build this efficiently with Go using tools you've already looked at (plus some clear, working examples):

Solution 1: Using gopdf (Full Control Over Page Sizes)

gopdf is powerful for custom PDF generation, and with a little extra code, it handles batch image conversion seamlessly.

Step 1: Install the dependency

go get github.com/signintech/gopdf

Step 2: Full Working Code

This script will walk through your image directory, add each image as a properly sized PDF page, and export a single PDF:

package main

import (
	"fmt"
	"image"
	_ "image/jpeg" // Required to decode JPEGs
	_ "image/png"  // Required to decode PNGs
	"os"
	"path/filepath"

	"github.com/signintech/gopdf"
)

func main() {
	// Update these paths to match your setup
	imageDirectory := "./your-images-folder"
	outputPath := "./converted-images.pdf"

	// Initialize PDF with default A4 (we'll adjust pages per image)
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})

	// Walk through all files in the image directory
	err := filepath.Walk(imageDirectory, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// Skip directories and non-image files
		if info.IsDir() {
			return nil
		}
		ext := filepath.Ext(path)
		if ext != ".jpg" && ext != ".jpeg" && ext != ".png" {
			return nil
		}

		// Open and decode the image to get its dimensions
		file, err := os.Open(path)
		if err != nil {
			fmt.Printf("Skipping %s: failed to open - %v\n", path, err)
			return nil
		}
		defer file.Close()

		img, _, err := image.Decode(file)
		if err != nil {
			fmt.Printf("Skipping %s: failed to decode - %v\n", path, err)
			return nil
		}
		imgWidth := float64(img.Bounds().Dx())
		imgHeight := float64(img.Bounds().Dy())

		// Calculate scaling to fit image within A4 (optional, remove if you want full-size pages)
		a4Width, a4Height := 595.28, 841.89 // A4 dimensions in points
		scale := min(a4Width/imgWidth, a4Height/imgHeight)
		if scale < 1 {
			imgWidth *= scale
			imgHeight *= scale
		}

		// Add a new page sized to fit the image
		pdf.AddPageWithSize(gopdf.PageSize{W: imgWidth, H: imgHeight})

		// Draw the image onto the page
		if err := pdf.Image(path, 0, 0, &gopdf.Rect{W: imgWidth, H: imgHeight}); err != nil {
			fmt.Printf("Skipping %s: failed to add to PDF - %v\n", path, err)
		}

		return nil
	})

	if err != nil {
		fmt.Printf("Error processing directory: %v\n", err)
		return
	}

	// Save the final PDF
	if err := pdf.WritePdf(outputPath); err != nil {
		fmt.Printf("Failed to save PDF: %v\n", err)
		return
	}

	fmt.Printf("Success! PDF saved to %s\n", outputPath)
}

// Helper to get the smaller of two floats
func min(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

Key Notes:

  • We explicitly register JPEG/PNG decoders (the standard library requires this to decode image files)
  • The script skips invalid files instead of crashing, so it's robust for messy directories
  • You can remove the scaling logic if you want each PDF page to match the exact size of the source image

Solution 2: Using Maroto (Simpler, Layout-Focused)

If you prefer cleaner code without manual size calculations, Maroto works great—it's built for report generation but handles images effortlessly.

Step 1: Install the dependency

go get github.com/johnfercher/maroto/v2

Step 2: Full Working Code

This will create a single PDF with each image centered on its own A4 page:

package main

import (
	"os"
	"path/filepath"

	"github.com/johnfercher/maroto/v2"
	"github.com/johnfercher/maroto/v2/pkg/components/image"
	"github.com/johnfercher/maroto/v2/pkg/config"
	"github.com/johnfercher/maroto/v2/pkg/props"
)

func main() {
	imageDirectory := "./your-images-folder"
	outputPath := "./maroto-output.pdf"

	// Initialize Maroto with A4 portrait orientation
	m := maroto.NewMaroto(config.Portrait, config.A4)
	m.SetPageMargins(10, 10, 10) // Add small margins around images

	// Collect all image paths first
	var imagePaths []string
	filepath.Walk(imageDirectory, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			ext := filepath.Ext(path)
			if ext == ".jpg" || ext == ".jpeg" || ext == ".png" {
				imagePaths = append(imagePaths, path)
			}
		}
		return nil
	})

	// Add each image as a full-width row on a new page
	for _, path := range imagePaths {
		// Add a row that takes up most of the page height, center the image
		m.AddRow(277, image.NewFromFile(path, props.Rect{
			Center:  true,
			Percent: 90, // Image takes 90% of the row width
		}))
		m.AddPage()
	}

	// Remove the extra blank page added at the end
	if len(imagePaths) > 0 {
		m.RemovePage(m.GetPageCount())
	}

	// Export the PDF
	if err := m.OutputFileAndClose(outputPath); err != nil {
		panic(err)
	}

	fmt.Printf("PDF saved successfully to %s\n", outputPath)
}

Key Notes:

  • Maroto handles page sizing and layout automatically, so you don't have to calculate dimensions manually
  • The Percent property ensures images scale to fit the page without overflowing

Both of these solutions will be way faster than your Python implementation thanks to Go's compiled performance and efficient I/O handling. Pick the one that fits your need for control vs. simplicity!

内容的提问来源于stack exchange,提问作者D3crypt360

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:22:42