Как загрузить PNG и экспортировать в TGA, сохраняя альфа в C#?

Я пишу инструмент для автоматизации создания наших активов для игры. Я хочу взять папку с файлами PNG, объединить их в текстурный атлас, а затем экспортировать атлас в виде TGA и UV-координаты в XML.

Я не уверен, какой метод я должен использовать, чтобы загрузить файлы PNG в C#, как кажется, их несколько. Каков рекомендуемый метод загрузки изображений в C#, который дает доступ к цветным / альфа-данным, чтобы я мог извлечь их в TGA?

У меня также уже есть код создания TGA на C++, который я планирую переместить на C#, но мне интересно, есть ли что-нибудь уже доступное в.Net для создания / сохранения TGA?

Спасибо за прочтение.

2 ответа

Решение

Загрузка файла PNG в растровое изображение.Net очень проста:

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

После загрузки растрового изображения вы можете наиболее эффективно получить доступ ко всей его информации (включая информацию об альфа-канале), используя метод LockBits для растрового изображения (в Stackru существует множество примеров кода LockBits).

Обновление: вот пример кода, который показывает, как использовать LockBits для доступа к данным 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);

Вам нужно установить опцию компилятора "Разрешить небезопасный код" для вашего проекта, чтобы использовать этот код. Вы также можете использовать метод GetPixel(x, y) растрового изображения, но это удивительно медленно.

У меня нет примера кода, но я могу дать вам руководство

  1. Загрузите PNG, используя Image.FromFile(). .NET поддерживает загрузку PNG
  2. Откройте дескриптор файла к вашей тарге. Создайте XmlDocument. .NET не поддерживает targa, поэтому вы должны написать его вручную.
  3. Заблокируйте растровое изображение, чтобы получить пиксели. GetPixel() очень медленный. Я думаю, что метод называется LockBits(). Вы получаете указатель на поверхность для чтения пикселей
  4. Пиши в таргу. Targa - это контейнерный формат, поэтому подойдет любое растровое изображение.
  5. Сохраните УФ как XML.

Формат тарга

Хотите использовать палитру? Поскольку вы создаете игру, я бы порекомендовал вам вычислить палитру для ваших растровых изображений и поместить ее в targa, чтобы уменьшить размер файла.

О, прежде чем я забуду, .NET не использует RGBA, вместо этого пиксели являются BGRA. Не спрашивайте меня, почему, но это так.

Другие вопросы по тегам