2017-10-18 5 views
0

J'ai besoin d'un petit conseil. Je crée des miniatures d'images dans Go et je voudrais les passer à jpegoptim pour les écraser. Jpegoptim a les drapeaux --stdin et --stdout, que je voudrais utiliser. Maintenant, je ne veux pas enregistrer l'image générée sur le disque d'abord, mais convertir mon * image.RGBA à quelque chose qui implémente io.Reader, donc je peux le passer à exec.Cmd.StdinMettre en œuvre io.Reader à partir de l'image.RGBA

Je suis un peu perdu sur la façon dont je pourrais y parvenir, serait génial si quelqu'un peut me diriger dans la bonne direction.

Merci

+2

Vous devez encoder l'image dans un certain format. Si vous voulez un jpeg, alors regardez le paquet jpeg: https://golang.org/pkg/image/jpeg/#Encode – JimB

+0

Merci @JimB Donc, par exemple, je code pour un bytes.Buffer et peut l'utiliser directement car il implémente aussi le io.Reader, non? – tsdtsdtsd

Répondre

1

Dans ce cas, vous n'avez pas besoin de mettre en œuvre votre propre io.Reader. Utilisez io.Pipe et jpeg.Encode, par ex.

func main() { 
    //Prepare image ... 
    img := ... 

    //Prepare output (file etc.) ... 
    outFile := ... 

    //Use pipe to connect JPEG encoder output to cmd's STDIN 
    pr, pw := io.Pipe() 

    //Exec jpegoptim in goroutine 
    done := make(chan bool, 1) 
    go func() { 
     //execute command 
     cmdErr := bytes.Buffer{} 
     cmd := exec.Command("jpegoptim", "--stdin", "--verbose") 
     cmd.Stdin = pr  //image input from PIPE 
     cmd.Stderr = &cmdErr //message 
     cmd.Stdout = outFile //optimize image output 

     if err := cmd.Run(); err != nil { 
      // handle error 
     } 
     fmt.Printf("Result: %s\n", cmdErr.String()) 
     close(done) 
    }() 

    //ENCODE image to JPEG then write to PIPE 
    o := jpeg.Options{Quality: 90} 
    jpeg.Encode(pw, img, &o) 

    //When done, close the PIPE 
    if err := pw.Close(); err != nil { 
     // handle error 
    } 

    //Wait for jpegoptim 
    <-done 
}