1
votes

ImageMagick convertit en png8 (PNG palettisé avec alpha binaire) en utilisant la couleur d'arrière-plan pour les pixels partiellement transparents

J'ai une image PNG 32 bits comme celle-ci:

32 bits

Affiché ici avec un arrière-plan en damier pour la visibilité, mais au lieu du damier, l'image est en fait transparente (pour votre référence: l'image 32 bits d'origine ). Comme vous pouvez le voir, sur les bords et vers la droite, les pixels rouges passent progressivement d'opaque à transparent.

Si j'affiche cette image 32 bits sur un arrière-plan bleu, les pixels sur les bords et vers la droite passeraient progressivement du rouge au bleu.

Je dois maintenant convertir cette image en PNG 8 bits avec alpha binaire. Je souhaite que la zone entièrement transparente reste totalement transparente, mais que les pixels partiellement transparents se fondent progressivement avec la couleur d'arrière-plan / matte souhaitée , dans cet exemple en bleu.

Donc quelque chose comme ça:

8 bits mélangés avec la couleur d'arrière-plan

Cependant, je n'arrive pas à comprendre comment faire cela avec ImageMagick (en utilisant ImageMagick 7.0.8-26 sur Mac). J'ai essayé comme suit:

magick original.png -background 'rgba (0,0,255,0)' png8: output.png

Mais cela se traduit par:

8 bits avec couleur d'arrière-plan ignorée

Il semble ignorer complètement la couleur de fond bleu, et simplement convertir la transparence en binaire (prenant probablement complètement opaque pour ≥128 ou complètement transparent pour <128).

De plus, si je spécifie rgb (0,0,255) comme couleur d'arrière-plan (c'est-à-dire sans alpha), le résultat est le même.

ImageMagick propose-t-il une option intelligente de «fusion d'arrière-plan pour les pixels partiellement transparents» que je ne connais pas?

Sinon, je suppose que je devrais en quelque sorte extraire un bitmap binaire où l'image d'origine est entièrement transparente (c'est-à-dire avoir une valeur alpha ou une opacité 0), puis aplatir l'image sur un arrière-plan de mon choix, puis réappliquer le bitmap alpha booléen à nouveau. Mais je ne sais pas trop comment procéder.


0 commentaires

4 Réponses :


2
votes

Je peux penser à deux techniques, mais je suis sûr que les gens ont de meilleures réponses.

Première option

Composez le fond bleu, puis copiez le canal alpha à partir de la source d'origine. p>

magick original.png \( \
  +clone -fill BLUE -draw 'color 0,0 reset' \) \
  -compose DstOver -composite -transparent BLUE \
  PNG8:output.png

 output

Deuxième option

Remplacez transparent par la couleur bleue, puis appelez -transparent sans aucune opération -fuzz .

magick original.png \( \
  +clone \( +clone -fill BLUE -draw 'color 0,0 reset' \) \
  -compose DstOver -composite \) \
  -swap 0,1 -compose CopyAlpha -composite  PNG8:output.png

 output

Encore une fois, je suis sûr que les exemples ci-dessus peuvent être améliorés. YMMV


0 commentaires

2
votes

Une façon de faire cela avec ImageMagick est d'extraire le canal alpha, de coloriser essentiellement tout sauf les pixels totalement transparents, et de composer l'image originale sur le résultat.

convert input.png \( +clone -alpha extract -transparent black -fill blue \
   -channel RGB -colorize 100 +channel \) +insert -composite output.png

Cela lit l'entrée l'image, la clone à l'intérieur des parenthèses et extrait le canal alpha en un masque noir et blanc.

Le noir pur est rendu transparent avec "-transparent black".

Le blanc, tout sauf le noir pur, est changé en bleu avec "-colorize 100". Le réglage "-channel RGB" applique cette couleur de remplissage uniquement à la partie blanche du masque et ignore le transparent.

Ensuite, après les parenthèses, le "+ insert" déplace cette image bleu sur transparent vers l'arrière , et "-composite" place l'image d'entrée sur cette image bleue et transparente.

Si vous utilisez ImageMagick version 7, utilisez "magick" au lieu de "convert". Si vous utilisez Windows, remplacez la barre oblique inverse de fin de ligne "\" par un signe "^", et supprimez les barres obliques inverses qui échappent aux parenthèses "\ (... \)" par simplement "(...)" .


0 commentaires

0
votes

Grâce aux suggestions publiées, le problème est que je ne veux pas masquer une couleur particulière (comme le noir ou le bleu) comme transparente. Cette même couleur exacte peut également apparaître dans les parties non transparentes.

Après quelques ajustements, j'ai obtenu le résultat exact dont j'avais besoin:

magick original.png -write MPR: foo -background 'rgb (0,0,255)' -flatten \ (MPR: foo -alpha extract -threshold 0 \) -compose copy_opacity -composite png8: result.png

Explication:

  • Je commence par original.png et j'utilise -write MPR: foo pour enregistrer une copie temporaire en mémoire appelée 'foo'
  • Ensuite, j'aplatis l'image sur un fond bleu, en donnant les valeurs de couleur correctes partout (y compris en fusionnant avec l'arrière-plan pour les pixels partiellement transparents) mais en perdant les données d'opacité.
  • Ensuite, je traite un deuxième calque de côté, ouvrant la même image d'entrée d'origine (restauration à partir de la mémoire en utilisant MPR: foo ) et extrayez son canal alpha qui devient maintenant une image en niveaux de gris, contenant l'alpha d'origine données.
  • J'applique -threshold 0 sur ce calque, ce qui change toutes les valeurs de canal qui étaient> 0 au maximum (c'est-à-dire alpha 255 ou totalement opaque) et ≤0 reste 0 (totalement transparent). C'est donc maintenant mon canal "alpha binaire".
  • Enfin, je fusionne ces deux calques en utilisant un composite copy_opacity qui ne fait que copier le 2ème calque (l'alpha binaire) et l'écrit comme données alpha du calque résultant.
  • L'enregistrement du résultat final me donne l'image exacte dont j'ai besoin.

0 commentaires

1
votes

Voici une autre méthode dans ImageMagick.

 entrez la description de l'image ici

Read the image.

Clone it, extract the alpha channel, create transparent blue color map and apply to the alpha channel, then threshold the alpha channel.

Swap the two images and composite the original over the processed alpha channel.

Save the output.


OU POUR Imagemgick 7

magick img.png \
\( -clone 0 -alpha extract -alpha copy -channel rgba \
\( xc:none xc:blue +append \) -clut \
-channel alpha -threshold 0 +channel \) \
+swap -compose over -composite PNG8:result.png

entrez la description de l'image ici

convert img.png \
\( -clone 0 -alpha extract -channel rgba \
    \( xc:none xc:blue +append \) -clut +channel \
        -channel alpha -threshold 0 +channel \) \
+swap -compose over -composite PNG8:result.png


9 commentaires

Merci, j'aime encore mieux cette approche car elle ne recharge pas l'image d'origine. Je ne pouvais pas trouver un moyen de fusionner l'original transparent sur un fond bleu sans aplatir toute la pile. Cependant, quelque chose est toujours éteint, si j'exécute votre ligne de commande, l'image résultante a un fond noir au lieu de transparent?


Je ne comprends pas. Mon résultat affiché ci-dessus n'a-t-il pas un fond transparent? Enregistrez-vous au format JPG plutôt que PNG? Quelle est notre version d'ImageMagick, la date de la version et la plateforme? Avez-vous commencé avec votre entrée transparente d'origine?


Oui, certainement, en utilisant le PNG transparent 32 bits comme image d'entrée. Et la sortie au format PNG également. J'utilise exactement la même ligne de commande que vous avez publiée. Ma version IM est ImageMagick 7.0.8-26 sur Mac. Etrange hein?


Peut-être que cette version avait un bogue. Essayez de mettre à niveau vers la version actuelle, qui est actuellement la version 7.0.8.49.


J'ai réessayé après la mise à jour de ma messagerie instantanée qui est maintenant 7.0.8-49 Q16 x86_64 2019-06-13 . Mais curieusement, toujours le même résultat .


Utilisez magick not convert sur ImageMagick 7. Avez-vous installé lcms2? Quelle est votre version de libpng?


J'ai essayé magick au lieu de convert , aucune différence. Je ne suis pas au courant d'avoir installé activement lcms2 ou libpng moi-même (n'est-ce pas seulement inclus avec ImageMagick?) Mais si je fais brew info lcms2 j'obtiens "stable 2.9", et brew info libpng donne "stable 1.6.37".


Je peux dupliquer votre mauvais résultat sur ImageMagick 7. Permettez-moi de faire quelques expériences pour trouver la bonne commande pour IM 7. Je posterai de nouveau à ma réponse originale.


D'ACCORD. La solution pour IM 7 est légèrement différente. Il a besoin d'une copie -alpha avant -channel rgba. Je poste la solution complète dans ma réponse.