Changer la couleur de fond d’une image anti-aliasée en utilisant C # avec anti-aliasing

J’ai une image dont je dois changer la couleur d’arrière-plan (par exemple, changer l’arrière-plan de l’exemple d’image ci-dessous en bleu).

Cependant, l’image est anti-aliasée, je ne peux donc pas simplement remplacer la couleur d’arrière-plan par une couleur différente.

L’une des méthodes que j’ai essayée consiste à créer une deuxième image qui n’est que l’arrière-plan, à en changer la couleur et à fusionner les deux images en une seule. Toutefois, cela ne fonctionne pas car la frontière entre les deux images est floue.

Y a-t-il un moyen de faire cela, ou un autre moyen d’y parvenir que je n’ai pas envisagé?

Exemple d’image

Abstraitement

Chaque pixel de votre image est un vecteur (R, V, B), où chaque composant est dans la plage [0, 1]. Vous voulez une transformation, T, qui convertira tous les pixels de votre image en une nouvelle (R ‘, G’, B ‘) sous les contraintes suivantes:

  • le noir doit restr noir
    • T (0, 0, 0) = (0, 0, 0)
  • le blanc devrait devenir la couleur de votre choix C *
    • T (1, 1, 1) = C *

Une façon simple de faire ceci est de choisir la transformation suivante T:

T(c) = C* .* c (where .* denotes element-wise multiplication) 

Ceci est juste la multiplication d’image standard.

Concrètement

Si les performances ne vous inquiètent pas, vous pouvez utiliser les méthodes (très lentes) GetPixel et SetPixel sur votre Bitmap pour appliquer cette transformation à chaque pixel de celle-ci. Si vous ne savez pas comment faire cela, dites-le simplement dans un commentaire et j’appendai une explication détaillée pour cette partie.

Comparaison

Comparez cela à la méthode présentée par LarsTech. La méthode présentée ici est au top; la méthode présentée par LarsTech est en bas. Notez les effets de bord indésirables sur l’icône du bas (voile blanche sur les bords).

Comparaison

Et voici la différence d’image entre les deux:

Différence

Après coup

Si votre image source a un arrière-plan transparent (c’est-à-dire blanc transparent) et un avant-plan noir (comme dans votre exemple), vous pouvez simplement effectuer votre transformation T (a, r, g, b) = (a, 0, 0, 0 ) puis tracez votre image sur la couleur de fond souhaitée, comme suggéré par LarsTech.

Juste en utilisant GDI +

 Image image = Image.FromFile("cloud.png"); Bitmap bmp = new Bitmap(image.Width, image.Height); using (Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.SkyBlue); g.InterpolationMode = InterpolationMode.NearestNeighbor; g.PixelOffsetMode = PixelOffsetMode.None; g.DrawImage(image, Point.Empty); } 

abouti à:

entrez la description de l'image ici

Si vous souhaitez remplacer une couleur uniforme, vous pouvez la convertir en alpha. Je ne voudrais pas le coder moi-même!

Vous pouvez utiliser le code source Color To Alpha de GIMP (en version GPL), en voici une version

PS Pas sûr de savoir comment obtenir les dernières nouvelles.

Suppression / remplacement de fond, IMO est plus un art que la science, vous ne trouverez pas un algorithme qui convienne à toutes les solutions pour cela MAIS, selon votre désir désespéré ou intéressé de résoudre ce problème, vous pouvez envisager les explications suivantes:

Supposons que vous avez une image en couleur.

Utilisez votre choix de mécanisme de décodage et générez une image en niveaux de gris / luminosité de votre image couleur.

Tracez un graphique (parlant métaphoriquement) de la valeur numérique du pixel (x) par rapport au nombre de pixels de l’image pour cette valeur (y). Alias. un histogramme de luminosité.

Maintenant, si votre arrière-plan est assez grand (ou petit), vous verrez une partie du graphique représentant la dissortingbution d’une plage de pixels qui constituent votre arrière-plan. Vous pouvez choisir une plage légèrement plus large pour traiter l’anti-aliasing (basé sur un décalage fixe que vous définissez si vous avez affaire à des images similaires) et appelez-la plage de luminosité pour votre arrière-plan.

Cela vous faciliterait la vie si vous connaissiez au moins un pixel (échantillon / valeur de pixel médiane) en dehors de la plage de pixels qui définit votre arrière-plan. Vous pourrez ainsi “rechercher” la partie du graphique qui définit votre arrière-plan.

Une fois que vous avez la plage de pixels de luminosité pour l’arrière-plan, vous pouvez parcourir les pixels de l’image originale, comparer leurs valeurs de luminosité à la plage qui vous convient. Remplacer le pixel de l’image d’origine par la couleur souhaitée, de préférence la luminosité. décalé en fonction du pixel d’origine et du pixel échantillon, de sorte que l’arrière-plan remplacé est également anti-aliasé.

Ce n’est pas une solution parfaite et il existe de nombreux scénarios d’échec partiel ou partiel, mais là encore, cela fonctionnerait pour l’exemple d’image que vous avez joint à votre question.

Il existe également de nombreuses possibilités d’amélioration des performances, notamment GPGPU, etc.

Une autre solution possible consisterait à utiliser certaines des bibliothèques de traitement d’images tierces prédéfinies. Il existe quelques logiciels libres tels que Camellia, mais je ne suis pas sûr des fonctionnalités fournies ni de leur niveau de sophistication.