2009-10-03 5 views
6

J'écris un outil pour automatiser certains de nos actifs pour un jeu. Ce que je veux faire est de prendre un dossier de fichiers PNG, les combiner dans un atlas de texture, puis exporter l'atlas en tant que TGA et les coordonnées UV en XML. Je ne suis pas sûr de la méthode que je devrais utiliser pour charger les fichiers PNG en C# car il semble y en avoir plusieurs. Quelle est la méthode recommandée pour charger des images en C# qui donne accès aux données couleur/alpha pour que je puisse les extraire au TGA?Comment charger les fichiers PNG et exporter au format TGA en gardant alpha en C#?

J'ai aussi déjà du code de création TGA en C++ que je prévois de déplacer en C# mais je me demande s'il y a quelque chose de déjà disponible en .Net pour créer/enregistrer des TGA?

Merci d'avoir lu.

Répondre

8

Charger un fichier PNG dans un .Net Bitmap est facile:

Bitmap bmp = (Bitmap)Bitmap.FromFile("c:\wherever\whatever.png"); 
// yes, the (Bitmap) cast is necessary. Don't ask me why. 

Une fois que vous avez le Bitmap chargé, vous pouvez accéder à toutes ses informations (y compris les informations de canal alpha) le plus efficacement possible en utilisant la méthode LockBits de Bitmap (Il existe de nombreux exemples de code LockBits sur StackOverflow).

Mise à jour: voici un exemple de code qui montre comment utiliser LockBits pour accéder à la pixel par pixel des données de Bitmap:

System.Drawing.Imaging.BitmapData data = 
    bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), 
    System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat); 
unsafe 
{ 
    // important to use the BitmapData object's Width and Height 
    // properties instead of the Bitmap's. 
    for (int x = 0; x < data.Width; x++) 
    { 
     int columnOffset = x * 4; 
     for (int y = 0; y < data.Height; y++) 
     { 
      byte* row = (byte*)data.Scan0 + (y * data.Stride); 
      byte B = row[columnOffset]; 
      byte G = row[columnOffset + 1]; 
      byte R = row[columnOffset + 2]; 
      byte alpha = row[columnOffset + 3]; 
     } 
    } 
} 
bmp.UnlockBits(data); 

Vous devez définir le « Autoriser code non sécurisé » option du compilateur pour votre projet d'utiliser ce code. Vous pouvez également utiliser la méthode GetPixel (x, y) de Bitmap, mais c'est incroyablement lent.

+0

La conversion est nécessaire car Bitmap.FromFile n'existe pas réellement - il appelle la méthode statique Image.FromFile de la classe de base. – bobbymcr

+0

@bobbymcr: bien sûr, mais pourquoi Bitmap ne remplace-t-il pas FromFile, appelle-t-il base.FromFile et affiche l'image renvoyée en tant que bitmap? – MusiGenesis

0

Je n'ai pas un exemple de code, mais je peux vous donner une ligne directrice

  1. charge PNG à l'aide Image.FromFile(). .NET prend en charge le chargement PNG
  2. Ouvrez une poignée de fichier sur votre targa. Créer un XmlDocument .NET ne supporte pas targa, vous devez donc l'écrire manuellement.
  3. Verrouillez le bitmap pour obtenir les pixels. GetPixel() est très lent. Je pense que la méthode s'appelle LockBits(). Vous obtenez un pointeur sur la surface pour lire les pixels
  4. Ecrivez sur targa. Targa est un format conteneur, donc tout bitmap devrait convenir.
  5. Enregistrer les UV en tant que Xml.

Targa format

Voulez-vous utiliser une palette? Depuis que vous créez un jeu, je vous recommande de calculer une palette pour vos bitmaps et de le mettre dans le targa pour réduire la taille du fichier. Oh, avant que j'oublie, .NET n'utilise pas RGBA, à la place, les pixels sont BGRA. Ne me demandez pas pourquoi, mais c'est comme ça.

Questions connexes