From 61f65c6c039de0e916f5e58411080cd433707949 Mon Sep 17 00:00:00 2001 From: kpym Date: Wed, 21 Oct 2020 13:28:20 +0200 Subject: [PATCH] des PNG et GIF en 16 couleurs (donc plus petits) --- marianne.go | 192 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 76 deletions(-) diff --git a/marianne.go b/marianne.go index ec90e1d..82d72e4 100644 --- a/marianne.go +++ b/marianne.go @@ -4,6 +4,10 @@ import ( "bytes" "flag" "fmt" + "image" + "image/color" + "image/gif" + "image/png" "io/ioutil" "math" "os" @@ -159,55 +163,7 @@ func draw(ctx *canvas.Context, institution, direction string) { } } -func main() { - // déclare les flags - nom = flag.String("nom", "logo", "Le nom du fichier.") - institution = flag.String("institution", "RÉPUBLIQUE\\FRANÇAISE", "Le nom du ministère, ambassade, ...") - direction = flag.String("direction", "", "Intitulé de de direction, service ou délégations interministérielles.") - eol = flag.String("eol", "\\", "Le passage à la ligne, en plus du EOL standard.") - hauteurs = flag.String("hauteurs", "100,300,700", "Les hauteurs pour les logos en PNG et JPG.") - formats = flag.String("formats", "SVG", "Les formats parmi SVG, PDF, PNG, GIF et JPG.") - avecMarges = flag.Bool("avec-marges", false, "Avec zone de protection autour du logo. Ce paramètre est compatible avec -sans-marges.") - sansMarges = flag.Bool("sans-marges", false, "Sans zone de protection autour du logo. Ce paramètre est compatible avec -avec-marges.") - pourSignature = flag.Bool("pour-signature", false, "Le logo est destiné à une signature mail.") - silence = flag.Bool("silence", false, "N'imprime rien.") - // Message d'aide - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "marianne (version: %s)\n\n", version) - fmt.Fprintf(os.Stderr, "Ce programme génère le logo de l'institution.\nParamètres disponibles:\n\n") - flag.PrintDefaults() - fmt.Fprintf(os.Stderr, "\n") - } - // récupère les flags - flag.Parse() - // au moins une des versions doit être présente (avec marges par défaut) - if !*sansMarges { - *avecMarges = true - } - // silence ? - if *silence { - log = func(msg ...interface{}) {} - } - - // le canevas et le contexte sur lesquels on va dessiner - c := canvas.New(1, 1) // la taille sera ajustée après avec Fit() - ctx := canvas.NewContext(c) - log("Création du logo ...") - draw(ctx, *institution, *direction) - log("fait.\n") - - if *sansMarges { - c.Fit(0.0) - log("\nEnregistrement sans marges :\n") - writeImages(onWhite(c), "_szp", strings.ToLower(*formats)) - } - if *avecMarges { - c.Fit(x) - log("\nEnregistrement avec marges :\n") - writeImages(onWhite(c), "", strings.ToLower(*formats)) - } -} - +// le logo est mis sur fond blanc func onWhite(c *canvas.Canvas) *canvas.Canvas { cn := canvas.New(c.W, c.H) ctx := canvas.NewContext(cn) @@ -218,7 +174,41 @@ func onWhite(c *canvas.Canvas) *canvas.Canvas { return cn } -// Créer les fichiers : svg, pdf, png, ... +// les 16 couleurs du logo pour PNG et GIF +var MariannePalette16 = color.Palette{ + color.RGBA{0x0c, 0x0c, 0x0c, 0xff}, + color.RGBA{0xff, 0xff, 0xff, 0xff}, + color.RGBA{0x79, 0x79, 0x7c, 0xff}, + color.RGBA{0xa3, 0xa3, 0xa4, 0xff}, + color.RGBA{0x09, 0x09, 0x94, 0xff}, + color.RGBA{0xd7, 0xd7, 0xd9, 0xff}, + color.RGBA{0xe1, 0x04, 0x11, 0xff}, + color.RGBA{0xf2, 0xf2, 0xf2, 0xff}, + color.RGBA{0xf9, 0xcb, 0xce, 0xff}, + color.RGBA{0xc1, 0xc0, 0xc1, 0xff}, + color.RGBA{0x47, 0x47, 0x47, 0xff}, + color.RGBA{0xed, 0x5f, 0x70, 0xff}, + color.RGBA{0xfb, 0xdd, 0xdf, 0xff}, + color.RGBA{0xf0, 0xf0, 0xf9, 0xff}, + color.RGBA{0xe7, 0xe7, 0xe7, 0xff}, + color.RGBA{0xfa, 0xfa, 0xfa, 0xff}, +} + +type MarianneQuantizer struct { +} + +func (q *MarianneQuantizer) Quantize(p color.Palette, m image.Image) color.Palette { + return MariannePalette16 +} + +// transforme les chemins du canevas en image 16 couleurs +func CanvasToIndexedImg(c *canvas.Canvas, h int, p color.Palette) image.Image { + img := image.NewPaletted(image.Rect(0, 0, int(c.W*float64(h)/c.H+0.5), h), p) + c.Render(rasterizer.New(img, canvas.DPMM(float64(h)/c.H))) + return img +} + +// Créer les fichiers : svg, pdf, eps, png, gif, jpg // - c : le canvas contenant l'image // - zp : chaîne "sans zone de protection" a rajouter au nom ou pas func writeImages(c *canvas.Canvas, zp, formats string) { @@ -258,36 +248,86 @@ func writeImages(c *canvas.Canvas, zp, formats string) { } heights := stoi(*hauteurs) - // création du PNG - if strings.Contains(formats, "png") { - log("PNG de hauteur ...") - for i := 0; i < len(heights); i++ { - name := fmt.Sprintf("%s%s_%d.png", *nom, zp, heights[i]) - c.WriteFile(name, rasterizer.PNGWriter(canvas.DPMM(float64(heights[i])/c.H))) - log(heights[i], "...") + for i := 0; i < len(heights); i++ { + log("Image de hauteur ", heights[i], ".") + // la base du nom (sans l'extension) + name := fmt.Sprintf("%s%s_%d.", *nom, zp, heights[i]) + + // Création PNG et GIF (en 16 couleurs) + if strings.Contains(formats, "png") || strings.Contains(formats, "gif") { + img := CanvasToIndexedImg(c, heights[i], MariannePalette16) + if strings.Contains(formats, "png") { + dstFile, err := os.Create(name + "png") + check(err) + defer dstFile.Close() + png.Encode(dstFile, img) + log("..png.") + } + if strings.Contains(formats, "gif") { + dstFile, err := os.Create(name + "gif") + check(err) + defer dstFile.Close() + gif.Encode(dstFile, img, nil) + log("..gif.") + } } - log("fait.\n") - } - // création du JPG - if strings.Contains(formats, "jpg") || strings.Contains(formats, "jpeg") { - log("JPG de hauteur ...") - for i := 0; i < len(heights); i++ { - name := fmt.Sprintf("%s%s_%d.jpg", *nom, zp, heights[i]) - c.WriteFile(name, rasterizer.JPGWriter(canvas.DPMM(float64(heights[i])/c.H), nil)) - log(heights[i], "...") + // création JPG + if strings.Contains(formats, "jpg") || strings.Contains(formats, "jpeg") { + c.WriteFile(name+"jpg", rasterizer.JPGWriter(canvas.DPMM(float64(heights[i])/c.H), nil)) + log("..jpg.") } - log("fait.\n") + + log(" Fait.\n") } - // création du JPG - if strings.Contains(formats, "gif") { - log("GIF de hauteur ...") - for i := 0; i < len(heights); i++ { - name := fmt.Sprintf("%s%s_%d.gif", *nom, zp, heights[i]) - c.WriteFile(name, rasterizer.GIFWriter(canvas.DPMM(float64(heights[i])/c.H), nil)) - log(heights[i], "...") - } - log("fait.\n") +} + +func main() { + // déclare les flags + nom = flag.String("nom", "logo", "Le nom du fichier.") + institution = flag.String("institution", "RÉPUBLIQUE\\FRANÇAISE", "Le nom du ministère, ambassade, ...") + direction = flag.String("direction", "", "Intitulé de de direction, service ou délégations interministérielles.") + eol = flag.String("eol", "\\", "Le passage à la ligne, en plus du EOL standard.") + hauteurs = flag.String("hauteurs", "100,300,700", "Les hauteurs pour les logos en PNG et JPG.") + formats = flag.String("formats", "SVG", "Les formats parmi SVG, PDF, PNG, GIF et JPG.") + avecMarges = flag.Bool("avec-marges", false, "Avec zone de protection autour du logo. Ce paramètre est compatible avec -sans-marges.") + sansMarges = flag.Bool("sans-marges", false, "Sans zone de protection autour du logo. Ce paramètre est compatible avec -avec-marges.") + pourSignature = flag.Bool("pour-signature", false, "Le logo est destiné à une signature mail.") + silence = flag.Bool("silence", false, "N'imprime rien.") + // Message d'aide + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "marianne (version: %s)\n\n", version) + fmt.Fprintf(os.Stderr, "Ce programme génère le logo de l'institution.\nParamètres disponibles:\n\n") + flag.PrintDefaults() + fmt.Fprintf(os.Stderr, "\n") + } + // récupère les flags + flag.Parse() + // au moins une des versions doit être présente (avec marges par défaut) + if !*sansMarges { + *avecMarges = true + } + // silence ? + if *silence { + log = func(msg ...interface{}) {} + } + + // le canevas et le contexte sur lesquels on va dessiner + c := canvas.New(1, 1) // la taille sera ajustée après avec Fit() + ctx := canvas.NewContext(c) + log("Création du logo ...") + draw(ctx, *institution, *direction) + log("fait.\n") + + if *sansMarges { + c.Fit(0.0) + log("\nEnregistrement sans marges :\n") + writeImages(onWhite(c), "_szp", strings.ToLower(*formats)) + } + if *avecMarges { + c.Fit(x) + log("\nEnregistrement avec marges :\n") + writeImages(onWhite(c), "", strings.ToLower(*formats)) } }