Exemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="_texture2D"></param>
        /// <returns></returns>
        public static byte[] EncodeToTGA(this Texture2D _texture2D)
        {
            const int iTgaHeaderSize       = 18;
            const int iBytesPerPixelRGB24  = 3; // 1 byte per channel (rgb)
            const int iBytesPerPixelARGB32 = 4; // ~ (rgba)

            var useAlpha       = SupportsAlpha(_texture2D.format);
            int iBytesPerPixel = useAlpha ? iBytesPerPixelARGB32 : iBytesPerPixelRGB24;

            //

            using (MemoryStream memoryStream = new MemoryStream(iTgaHeaderSize + _texture2D.width * _texture2D.height * iBytesPerPixel))
            {
                using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
                {
                    // Write TGA Header

                    binaryWriter.Write((byte)0);                    // IDLength (not in use)
                    binaryWriter.Write((byte)0);                    // ColorMapType (not in use)
                    binaryWriter.Write((byte)10);                   // DataTypeCode == 10 (Runlength encoded RGB images)
                    binaryWriter.Write((short)0);                   // ColorMapOrigin (not in use)
                    binaryWriter.Write((short)0);                   // ColorMapLength (not in use)
                    binaryWriter.Write((byte)0);                    // ColorMapDepth (not in use)
                    binaryWriter.Write((short)0);                   // Origin X
                    binaryWriter.Write((short)0);                   // Origin Y
                    binaryWriter.Write((short)_texture2D.width);    // Width
                    binaryWriter.Write((short)_texture2D.height);   // Height
                    binaryWriter.Write((byte)(iBytesPerPixel * 8)); // Bits Per Pixel
                    binaryWriter.Write((byte)0);                    // ImageDescriptor (not in use)

                    // Write RLE Encoded Pixels

                    Color32[] arPixels = _texture2D.GetPixels32();

                    const int iMaxPacketLength = 128;
                    int       iPacketStart     = 0;
                    int       iPacketEnd       = 0;

                    while (iPacketStart < arPixels.Length)
                    {
                        Color32 c32PreviousPixel = arPixels[iPacketStart];

                        // Get current Packet Type
                        RLEPacketType packetType = ExtTexture.PacketType(arPixels, iPacketStart);

                        // Find Packet End
                        int iReadEnd = Mathf.Min(iPacketStart + iMaxPacketLength, arPixels.Length);
                        for (iPacketEnd = iPacketStart + 1; iPacketEnd < iReadEnd; ++iPacketEnd)
                        {
                            bool bPreviousEqualsCurrent = ExtTexture.Equals(arPixels[iPacketEnd - 1], arPixels[iPacketEnd]);

                            // Packet End if change in Packet Type or if max Packet-Size reached
                            if (packetType == RLEPacketType.RAW && bPreviousEqualsCurrent ||
                                packetType == RLEPacketType.RLE && !bPreviousEqualsCurrent)
                            {
                                break;
                            }
                        }

                        // Write Packet

                        int iPacketLength = iPacketEnd - iPacketStart;

                        switch (packetType)
                        {
                        case RLEPacketType.RLE:

                            // Add RLE-Bit to PacketLength
                            binaryWriter.Write((byte)((iPacketLength - 1) | (1 << 7)));

                            binaryWriter.Write(c32PreviousPixel.b);
                            binaryWriter.Write(c32PreviousPixel.g);
                            binaryWriter.Write(c32PreviousPixel.r);

                            if (useAlpha)
                            {
                                binaryWriter.Write(c32PreviousPixel.a);
                            }

                            break;

                        case RLEPacketType.RAW:

                            binaryWriter.Write((byte)(iPacketLength - 1));

                            for (int iPacketPosition = iPacketStart; iPacketPosition < iPacketEnd; ++iPacketPosition)
                            {
                                binaryWriter.Write(arPixels[iPacketPosition].b);
                                binaryWriter.Write(arPixels[iPacketPosition].g);
                                binaryWriter.Write(arPixels[iPacketPosition].r);

                                if (useAlpha)
                                {
                                    binaryWriter.Write(arPixels[iPacketPosition].a);
                                }
                            }

                            break;
                        }

                        iPacketStart = iPacketEnd;
                    }
                }

                return(memoryStream.GetBuffer());
            }
        }
Exemplo n.º 2
0
    public static byte[] EncodeToTGA(this Texture2D _texture2D, Compression _compression = Compression.RLE)
    {
        const int iTgaHeaderSize       = 18;
        const int iBytesPerPixelRGB24  = 3; // 1 byte per channel (rgb)
        const int iBytesPerPixelARGB32 = 4; // ~ (rgba)

        int iBytesPerPixel = _texture2D.format == TextureFormat.ARGB32 || _texture2D.format == TextureFormat.RGBA32
            ? iBytesPerPixelARGB32
            : iBytesPerPixelRGB24;

        //

        using (MemoryStream memoryStream = new MemoryStream(iTgaHeaderSize + _texture2D.width * _texture2D.height * iBytesPerPixel))
        {
            using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
            {
                // Write TGA Header

                binaryWriter.Write((byte)0);                                           // IDLength (not in use)
                binaryWriter.Write((byte)0);                                           // ColorMapType (not in use)
                binaryWriter.Write((byte)(_compression == Compression.None ? 2 : 10)); // DataTypeCode (10 == Runlength encoded RGB images)
                binaryWriter.Write((short)0);                                          // ColorMapOrigin (not in use)
                binaryWriter.Write((short)0);                                          // ColorMapLength (not in use)
                binaryWriter.Write((byte)0);                                           // ColorMapDepth (not in use)
                binaryWriter.Write((short)0);                                          // Origin X
                binaryWriter.Write((short)0);                                          // Origin Y
                binaryWriter.Write((short)_texture2D.width);                           // Width
                binaryWriter.Write((short)_texture2D.height);                          // Height
                binaryWriter.Write((byte)(iBytesPerPixel * 8));                        // Bits Per Pixel
                binaryWriter.Write((byte)0);                                           // ImageDescriptor (not in use)

                Color32[] arPixels = _texture2D.GetPixels32();

                if (_compression == Compression.None)
                {
                    // Write all Pixels one after the other
                    for (int iPixel = 0; iPixel < arPixels.Length; iPixel++)
                    {
                        Color32 c32Pixel = arPixels[iPixel];
                        binaryWriter.Write(c32Pixel.b);
                        binaryWriter.Write(c32Pixel.g);
                        binaryWriter.Write(c32Pixel.r);

                        if (iBytesPerPixel == iBytesPerPixelARGB32)
                        {
                            binaryWriter.Write(c32Pixel.a);
                        }
                    }
                }
                else
                {
                    // Write RLE Encoded Pixels

                    const int iMaxPacketLength = 128;
                    int       iPacketStart     = 0;
                    int       iPacketEnd       = 0;

                    while (iPacketStart < arPixels.Length)
                    {
                        Color32 c32PreviousPixel = arPixels[iPacketStart];

                        // Get current Packet Type
                        RLEPacketType packetType = EncodeToTGAExtension.PacketType(arPixels, iPacketStart);

                        // Find Packet End
                        int iReadEnd = Mathf.Min(iPacketStart + iMaxPacketLength, arPixels.Length);
                        for (iPacketEnd = iPacketStart + 1; iPacketEnd < iReadEnd; ++iPacketEnd)
                        {
                            bool bPreviousEqualsCurrent = EncodeToTGAExtension.Equals(arPixels[iPacketEnd - 1], arPixels[iPacketEnd]);

                            // Packet End if change in Packet Type or if max Packet-Size reached
                            if (packetType == RLEPacketType.RAW && bPreviousEqualsCurrent ||
                                packetType == RLEPacketType.RLE && !bPreviousEqualsCurrent)
                            {
                                break;
                            }
                        }

                        // Write Packet

                        int iPacketLength = iPacketEnd - iPacketStart;

                        switch (packetType)
                        {
                        case RLEPacketType.RLE:

                            // Add RLE-Bit to PacketLength
                            binaryWriter.Write((byte)((iPacketLength - 1) | (1 << 7)));

                            binaryWriter.Write(c32PreviousPixel.b);
                            binaryWriter.Write(c32PreviousPixel.g);
                            binaryWriter.Write(c32PreviousPixel.r);

                            if (iBytesPerPixel == iBytesPerPixelARGB32)
                            {
                                binaryWriter.Write(c32PreviousPixel.a);
                            }

                            break;

                        case RLEPacketType.RAW:

                            binaryWriter.Write((byte)(iPacketLength - 1));

                            for (int iPacketPosition = iPacketStart; iPacketPosition < iPacketEnd; ++iPacketPosition)
                            {
                                Color32 c32Pixel = arPixels[iPacketPosition];
                                binaryWriter.Write(c32Pixel.b);
                                binaryWriter.Write(c32Pixel.g);
                                binaryWriter.Write(c32Pixel.r);

                                if (iBytesPerPixel == iBytesPerPixelARGB32)
                                {
                                    binaryWriter.Write(c32Pixel.a);
                                }
                            }

                            break;
                        }

                        iPacketStart = iPacketEnd;
                    }
                }

                binaryWriter.Write(0);               // Offset of meta-information (not in use)
                binaryWriter.Write(0);               // Offset of Developer-Area (not in use)
                binaryWriter.Write(c_arV2Signature); // ImageDescriptor (not in use)
            }

            return(memoryStream.ToArray());
        }
    }