github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/documents/miniatures.go (about)

     1  package documents
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"image"
     7  	_ "image/jpeg"
     8  	_ "image/png"
     9  	"io"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"strings"
    13  
    14  	"github.com/disintegration/imaging"
    15  )
    16  
    17  const (
    18  	MINIATURE_WIDTH  = 200 // in pixels
    19  	MINIATURE_HEIGHT = 300 // in pixels
    20  )
    21  
    22  // ComputeMiniature écrit réduit le document entrant à une image png.
    23  // Les formats supportés sont .pdf, .png, .jpg, .jpeg
    24  // Le format .pdf requiert l'utilisation de Ghostscript.
    25  func ComputeMiniature(filename string, doc io.Reader, miniature io.Writer) error {
    26  	ext := strings.ToLower(filepath.Ext(filename))
    27  	switch ext {
    28  	case ".pdf":
    29  		cmd := exec.Command("gs", "-sDEVICE=png16m", "-dFirstPage=1", "-dLastPage=1", "-sstdout=%stderr", "-sOutputFile=-",
    30  			"-dBATCH", "-q", "-dTextAlphaBits=4", "-dGraphicsAlphaBits=4", "-dPDFFitPage", fmt.Sprintf("-g%dx%d", MINIATURE_WIDTH, MINIATURE_HEIGHT), "-")
    31  		cmd.Stdin = doc
    32  		cmd.Stdout = miniature
    33  		if err := cmd.Run(); err != nil {
    34  			return fmt.Errorf("Impossible de générer la miniature : %s", err)
    35  		}
    36  	case ".png", ".jpg", ".jpeg":
    37  		srcImage, _, err := image.Decode(doc)
    38  		if err != nil {
    39  			return fmt.Errorf("Impossible de générer la miniature : %s", err)
    40  		}
    41  		if srcImage.Bounds().Dx() >= srcImage.Bounds().Dy() {
    42  			srcImage = imaging.Rotate270(srcImage)
    43  		}
    44  		dstImageFit := imaging.Thumbnail(srcImage, MINIATURE_WIDTH, MINIATURE_HEIGHT, imaging.Lanczos)
    45  		if err = imaging.Encode(miniature, dstImageFit, imaging.PNG); err != nil {
    46  			return fmt.Errorf("Impossible de générer la miniature : %s", err)
    47  		}
    48  	default:
    49  		return fmt.Errorf("Impossible de générer la miniature : format %s non supporté", ext)
    50  	}
    51  	return nil
    52  }
    53  
    54  // ComputeMiniature2 est un raccourci (voir ComputeMiniature)
    55  func ComputeMiniature2(pdfBytes []byte) (miniature []byte, err error) {
    56  	out := new(bytes.Buffer)
    57  	if err := ComputeMiniature(".pdf", bytes.NewReader(pdfBytes), out); err != nil {
    58  		return nil, err
    59  	}
    60  	return out.Bytes(), nil
    61  }