2010-02-06 7 views
3

Les gens, je suis sûr qu'il est assez facile, mais Google n'a pas aidé ...Comment superposer deux images (tableaux d'octets)

Voici la tâche - j'ai deux tableaux d'octets (comme ARVB), représentant mes images. Ils ont la même taille. Quelle opération dois-je effectuer (octet par octet) pour superposer une image à une autre? La deuxième image a une certaine transparence, qui doit être prise en compte.

Pour effacer, im la recherche d'un code comme ceci:

  bytes[] result = new bytes[first.Length]; 
      for(i = 0; i< first.Lenght;i++) 
      { 
       result[i] = first[i] !!%SOMETHING%!! second[i]; 
      } 

simples comme des suppositions opérateur OR (je sais - c'est stupide;)) ne ne fonctionne pas.

Merci pour vos réponses. Edit: je ne peux pas utiliser la bibliothèque standart en raison de problèmes de sécurité (toutes ces manipulations étranges se produisent sur Silverlight).

+0

Aucun problème) Mais la langue n'est pas si importante ici - la réponse est plus mathématique que le code ... – ALOR

Répondre

7

En supposant que vous travaillez réellement avec des bitmaps, vous trouverez probablement plus facile de laisser la bibliothèque faire cela pour vous.

La classe System.Drawing.Graphics possède une propriété CompositingMode qui peut être réglé sur SourceCopy (la valeur par défaut - écrasez la couleur de fond) ou SourceOver (mélange avec la couleur d'arrière-plan).

Voir MSDN: How to Use Compositing Mode to Control Alpha Blending pour plus de détails.

Si vous voulez juste le calcul brut, alpha blending est assez simple. Pour une valeur alpha un entre 0,0 et 1,0, le résultat devrait être:

(aOld * oldValue) + ((1 - aOld) * aNew * newValue) 

oldValue est la valeur précédente avant superposition, newValue est ce que vous voulez superposer avec et aOld et aNew sont les anciens et nouvelles valeurs alpha respectivement. Vous devez évidemment faire ce calcul pour les valeurs R, G et B séparément.

Voir aussi: Alpha Compositing (lien wiki) pour une explication plus complète.


Mise à jour: Je pense qu'il devrait être facile de comprendre comment adapter cela au code dans l'OP, mais je suppose que pas tout le monde est une personne de mathématiques.

Je vais supposer que le byte[] est une séquence répétitive de valeurs A, R, G, B (donc Length serait un multiple de 4). Si ce n'est pas le cas, vous devrez adapter ce code au format de stockage que vous utilisez.

bytes[] result = new bytes[first.Length]; 
for(i = 0; i < first.Length; i += 4) 
{ 
    byte a1 = first[i]; 
    byte a2 = second[i]; 
    byte r1 = first[i+1]; 
    byte r2 = second[i+1]; 
    byte g1 = first[i+2]; 
    byte g2 = second[i+2]; 
    byte b1 = first[i+3]; 
    byte b2 = second[i+3]; 

    byte a = a1 + (255 - a1) * a2/255; 
    byte r = r1 * a1/255 + r2 * (255 - a1) * a2/65025; 
    byte g = g1 * a1/255 + g2 * (255 - a1) * a2/65025; 
    byte b = b1 * a1/255 + b2 * (255 - a1) * a2/65025; 

    result[i] = a; 
    result[i+1] = r; 
    result[i+2] = g; 
    result[i+3] = b; 
} 
+1

Désolé, je n'ai pas expliqué complètement ... j'ai besoin de quelque chose de la façon dont j'ai écrit exactement. voir edit pls – ALOR

+0

@ALOR: Eh bien, c'est un peu difficile pour moi de vous donner une solution exactement dans le format que vous avez écrit, car un simple tableau d'octets ne me dit rien sur la façon dont les informations de couleur sont réellement stockées. Une valeur ARGB complète est de 4 octets (ou 'int'). Avez-vous des tableaux de 4 octets, un pour chaque canal? Est-ce que le tableau répète, c'est-à-dire A, alors R, puis G, puis B, puis A à nouveau? Y a-t-il des en-têtes? Qu'y a-t-il dans ce tableau? – Aaronaught

+0

Exactement ce dont j'avais besoin) Thx – ALOR

0

Je pense que vous avez la bonne idée. L'opération que vous utilisez dépend de ce que vous voulez pour la sortie.Voici quelques opérations qui sont utiles:

  1. moyenne - une façon courante de combiner
  2. minimum
  3. maximale
  4. bitwise remplacer
  5. XOR
  6. ou
  7. ajouter
  8. Soustraire
  9. multiplier l'image 1 valeur par (image 2 mise à l'échelle 0 à 1). Cela mettra plus de l'image 1 sur les endroits lumineux de l'image 2 et pas tellement sur les endroits sombres. Essayez-les et voyez ce que vous préférez, ou mieux encore, laissez l'utilisateur choisir.

Vous pouvez probablement ajouter ou or les octets de transparence et utiliser l'une des autres opérations pour chacune des trois couleurs.