Golang PDF转图片 拼接长图 压缩PDF及图片 输出JPEG

PDF转PNG主要是用到Xpdf的库

Golang PDF转图片 拼接长图 压缩PDF及图片 输出JPEG_第1张图片

根据操作系统选择命令行工具下载- Download the Xpdf command line tools:

在bin64目录下可以找到PDFTOPNG可执行文件

Golang PDF转图片 拼接长图 压缩PDF及图片 输出JPEG_第2张图片

运行该命令即可 

[pdftopng file.pdf ouput-image-name]
例:pdftopng in.pdf out-prefix

 根据该命令开始写脚本


首先该命令转出来的图片是多图形式的,图片名格式如下:ouput-name-%06d

Golang PDF转图片 拼接长图 压缩PDF及图片 输出JPEG_第3张图片

因此首先需要获取pdf页码

go get rsc.io/pdf

使用该第三方库打开pdf可获取页码数,即为多图数量

s, _ := pdf.Open("in.pdf") // 获取简历页码
s.NumPage()

 然后通过go调用命令行执行xpdf的可执行文件

// 执行pdf转png
cmd := exec.Command("./pdftopng", "in.pdf", name) // ./cmd + pdf + print
cmd.Run()

然后是读取图片方法,把png文件读取为image.Image对象

func GetImageFromFile(filePath string) (img image.Image, err error) {
	f1Src, err := os.Open(filePath)

	if err != nil {
		return nil, err
	}
	defer f1Src.Close()

	buff := make([]byte, 512) // why 512 bytes ? see http://golang.org/pkg/net/http/#DetectContentType
	_, err = f1Src.Read(buff)

	if err != nil {
		return nil, err
	}

	filetype := http.DetectContentType(buff)

	fmt.Println(filetype)

	fSrc, err := os.Open(filePath)
	defer fSrc.Close()

	img, err = png.Decode(fSrc)
	if err != nil {
		return nil, err
	}
	return img, nil
}

接下来是拼接长图方法,我们希望长图按多图竖向排列

//图片拼接
func MergeImageNew(base image.Image, mask image.Image, paddingX int, paddingY int) (*image.RGBA, error) {
	baseSrcBounds := base.Bounds().Max

	maskSrcBounds := mask.Bounds().Max

	newWidth := baseSrcBounds.X
	newHeight := baseSrcBounds.Y

	maskWidth := maskSrcBounds.X
	maskHeight := maskSrcBounds.Y

	des := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight+maskHeight)) // 底板 newHeight+maskHeight 竖向排列
	//首先将一个图片信息存入jpg
	draw.Draw(des, des.Bounds(), base, base.Bounds().Min, draw.Over)
	//将另外一张图片信息存入jpg
	draw.Draw(des, image.Rect(paddingX, newHeight-paddingY+maskHeight, (paddingX+maskWidth), (newHeight-paddingY)), mask, image.ZP, draw.Over)

	return des, nil
}

然后是把拼接结果保存为图片的方法

func SaveImage(p string, src image.Image) error {
	f, err := os.OpenFile(p, os.O_SYNC|os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		return err
	}
	defer f.Close()
	ext := filepath.Ext(p)
	if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") {
		err = jpeg.Encode(f, src, &jpeg.Options{Quality: 80})
	} else if strings.EqualFold(ext, ".png") {
		err = png.Encode(f, src)
	} else if strings.EqualFold(ext, ".gif") {
		err = gif.Encode(f, src, &gif.Options{NumColors: 256})
	}
	return err
}

最后开可以对结果图进行压缩

    s, _ := pdf.Open("in.pdf") // 获取简历页码
	name := "out-prefix"       // 输出简历图片名称

	// 执行pdf转png
	cmd := exec.Command("./pdftopng", "in.pdf", name) // ./cmd + pdf + print
	cmd.Run()

	// 拼接长图
	imgBase, _ := GetImageFromFile(name + "-" + fmt.Sprintf("%06d", 1) + ".png")
	for i := 2; i <= s.NumPage(); i++ {
		img, _ := GetImageFromFile(name + "-" + fmt.Sprintf("%06d", i) + ".png")
		imgBase, _ = MergeImageNew(imgBase, img, 0, 0)
	}

	// 压缩长图
	baseSrcBounds := imgBase.Bounds().Max
	newWidth := baseSrcBounds.X
	newHeight := baseSrcBounds.Y
	canvas := resize.Resize(uint(newWidth), uint(newHeight), imgBase, resize.Lanczos3)

	// 保存长图
	SaveImage(name+".jpeg", canvas)

你可能感兴趣的:(go,pdf,golang,后端)