Textur mithilfe von System.Drawing decodieren und codieren

Implemen tieren Sie einen Textur-Codec mithilfe von System.Drawing

Verwenden Sie die folgende Klasse, um Textur-Encoder und Textur-Decoder zu definieren:

using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Aspose.ThreeD.Render;
using System.Runtime.InteropServices;

namespace Aspose.ThreeD
{
    /// <summary>
    /// Uses System.Drawing for encoding/decoding textures for Aspose.3D textures.
    /// </summary>
    public class GdiPlusCodec : ITextureCodec, ITextureDecoder
    {
        class GdiPlusEncoder : ITextureEncoder
        {
            public string FileExtension { get; }
            private ImageCodecInfo encoder;
            public GdiPlusEncoder(ImageCodecInfo encoder, string ext)
            {
                this.encoder = encoder;
                FileExtension = ext;
            }

            public void Encode(TextureData texture, Stream stream)
            {
                var bmp = ToBitmap(texture);
                bmp.Save(stream, encoder, null);
            }
        }
        /// <summary>
        /// Convert <see cref="TextureData"/> to <see cref="Bitmap"/>
        /// </summary>
        /// <param name="td"></param>
        /// <returns></returns>
        public static Bitmap ToBitmap(TextureData td)
        {
            using (var map = td.MapPixels(PixelMapMode.ReadOnly, Render.PixelFormat.A8R8G8B8))
            {
                var ret = new Bitmap(td.Width, td.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                var bits = ret.LockBits(new Rectangle(0, 0, td.Width, td.Height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                for (int y = 0; y < td.Height; y++)
                {
                    var srcOffset = y * map.Stride;
                    var destination = bits.Scan0 + y * bits.Stride;
                    Marshal.Copy(map.Data, srcOffset, destination, map.Stride);
                }
                ret.UnlockBits(bits);
                return ret;
            }
        }

        /// <summary>
        /// Convert <see cref="Bitmap"/> to <see cref="TextureData"/>
        /// </summary>
        /// <param name="img"></param>
        /// <param name="reverseY"></param>
        /// <returns></returns>
        public static TextureData ToTextureData(Bitmap img, bool reverseY)
        {
            var ret = new TextureData(img.Width, img.Height, Render.PixelFormat.A8R8G8B8);
            var bits = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            using (var map = ret.MapPixels(PixelMapMode.WriteOnly))
            {
                for (int y = 0; y < map.Height; y++)
                {
                    IntPtr srcPtr = bits.Scan0;
                    if(reverseY)
                        srcPtr += (map.Height - y - 1) * bits.Stride;
                    else
                        srcPtr += y * bits.Stride;
                    var dstOffset = y * map.Stride;
                    Marshal.Copy(srcPtr, map.Data, dstOffset, map.Stride);
                }
            }
            img.UnlockBits(bits);
            return ret;
        }
        /// <summary>
        /// Decode texture from stream, return null if failed to decode.
        /// </summary>
        /// <param name="stream">Texture data source stream</param>
        /// <param name="reverseY">Flip the texture</param>
        /// <returns>Decoded texture data or null if not supported.</returns>
        public TextureData Decode(Stream stream, bool reverseY)
        {
            using (var img = (Bitmap)Image.FromStream(stream))
            {
                var ret = ToTextureData(img, reverseY);
                return ret;
            }
        }
        /// <summary>
        /// Gets supported texture decoders.
        /// </summary>
        /// <returns></returns>
        public ITextureDecoder[] GetDecoders()
        {
            return new ITextureDecoder[] { this };
        }
        /// <summary>
        /// Gets supported texture encoders. 
        /// </summary>
        /// <returns></returns>
        public ITextureEncoder[] GetEncoders()
        {
            List<ITextureEncoder> ret = new List<ITextureEncoder>();
            foreach (var encoder in ImageCodecInfo.GetImageEncoders())
            {
                if (encoder.FilenameExtension == null)
                    continue;
                var exts = encoder.FilenameExtension.Split(';');
                foreach(var fileExt in exts)
                {
                    var ext = fileExt;
                    int p = ext.IndexOf('.');
                    if (p != -1)
                        ext = ext.Substring(p + 1);
                    ret.Add(new GdiPlusEncoder(encoder, ext.ToLowerInvariant()));
                }
            }
            return ret.ToArray();
        }
    }
}

Registrieren Sie es bei Aspose.3D

Jetzt registrieren wir es in Aspsoe.3D:

    Aspose.ThreeD.Render.TextureCodec.RegisterCodec(new Aspose.ThreeD.GdiPlusCodec());

Wenn dieser Codec registriert wurde, können alle von System.Drawing unterstützten Bildformate in Texture Data.Save verwendet werden.