Como carregar PNGs e exportar para a TGA mantendo alfa em C#?
Pergunta
Estou escrevendo uma ferramenta para automatizar alguns de nossos ativos para um jogo. O que eu quero fazer é pegar uma pasta de arquivos PNG, combiná -los em um atlas de textura e, em seguida, exportar o Atlas como um TGA e os coordes UV para XML.
Não tenho certeza de qual método devo usar para carregar os arquivos PNG em C#, pois parece haver vários. Qual é o método recomendado para carregar imagens em C# que dão acesso aos dados de cores/alfa para que eu possa extraí -los para o TGA?
Eu também já tenho código de criação de TGA em C ++, que pretendo mudar para C#, mas estou me perguntando se já há algo disponível no .NET para criar/salvar TGAs?
Obrigado pela leitura.
Solução
Carregar um arquivo PNG em um .NET Bitmap é fácil:
Bitmap bmp = (Bitmap)Bitmap.FromFile("c:\wherever\whatever.png");
// yes, the (Bitmap) cast is necessary. Don't ask me why.
Depois de carregar o bitmap, você pode acessar todas as suas informações (incluindo informações do canal alfa) com mais eficiência usando o método Bitmap LockBits (existem muitas amostras de código de bloqueio no StackOverflow).
Atualizar: Aqui está uma amostra de código que mostra como usar lockbits para acessar os dados do bitmap pixel-by-pixel:
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);
Você precisa definir a opção "Permitir código inseguro" para que seu projeto use este código. Você também pode usar o método getPixel (x, y) do bitmap, mas isso é incrivelmente lento.
Outras dicas
Eu não tenho uma amostra de código, mas posso lhe dar uma diretriz
- Carregue PNG usando imagem.FromFile (). .NET suporta carregar png
- Abra um identificador de arquivo no seu Targa. Crie um XMLDocument. .NET não suporta Targa, então você precisa escrevê -lo manualmente.
- Bloqueie o bitmap para chegar aos pixels. Getpixel () é muito lento. Eu acho que o método é chamado Lockbits (). Você recebe um ponteiro para a superfície para ler os pixels
- Escreva para Targa. Targa é um formato de contêiner, portanto, qualquer bitmap deve se encaixar.
- Salve o UV como XML.
Você quer usar uma paleta? Desde que você está fazendo um jogo, eu recomendaria que você calcule uma paleta para seus bitmaps e colocasse isso no Targa para reduzir o tamanho do arquivo.
Ah, antes que eu esqueça, o .NET não usa RGBA, em vez disso, os pixels são bgra. Não me pergunte o porquê, mas é assim.