Пример #1
0
        public static Texture2D LoadTextureFromFile(SharpDX.Direct3D11.Device aDevice, string aFullPath)
        {
            Texture2D      result = null;
            ImagingFactory fac    = new ImagingFactory();

            BitmapDecoder     bc  = new SharpDX.WIC.BitmapDecoder(fac, aFullPath, DecodeOptions.CacheOnLoad);
            BitmapFrameDecode bfc = bc.GetFrame(0);
            FormatConverter   fc  = new FormatConverter(fac);

            System.Guid desiredFormat = PixelFormat.Format32bppBGRA;
            fc.Initialize(bfc, desiredFormat);

            float[] buffer = new float[fc.Size.Width * fc.Size.Height];

            bool canConvert = fc.CanConvert(bfc.PixelFormat, desiredFormat);

            fc.CopyPixels <float>(buffer);
            GCHandle handle      = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            float    sizeOfPixel = PixelFormat.GetBitsPerPixel(desiredFormat) / 8;

            if (sizeOfPixel != 4.0f)
            {
                throw new System.Exception("Unknown error");
            }

            DataBox db = new DataBox(handle.AddrOfPinnedObject(), fc.Size.Width * (int)sizeOfPixel, fc.Size.Width * fc.Size.Height * (int)sizeOfPixel);

            int width  = fc.Size.Width;
            int height = fc.Size.Height;

            Texture2DDescription fTextureDesc = new Texture2DDescription();

            fTextureDesc.CpuAccessFlags    = CpuAccessFlags.None;
            fTextureDesc.Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm;
            fTextureDesc.Width             = width;
            fTextureDesc.Height            = height;
            fTextureDesc.Usage             = ResourceUsage.Default;
            fTextureDesc.MipLevels         = 1;
            fTextureDesc.ArraySize         = 1;
            fTextureDesc.OptionFlags       = ResourceOptionFlags.None;
            fTextureDesc.BindFlags         = BindFlags.RenderTarget | BindFlags.ShaderResource;
            fTextureDesc.SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0);

            result = new Texture2D(aDevice, fTextureDesc, new DataBox[] { db });
            handle.Free();

            return(result);
        }
Пример #2
0
        private static void EncodeImage(ImagingFactory imagingFactory, Image image, WicFlags flags, Guid containerFormat, BitmapFrameEncode frame)
        {
            Guid pfGuid = ToWic(image.Format, false);

            frame.Initialize();
            frame.SetSize(image.Width, image.Height);
            frame.SetResolution(72, 72);
            Guid targetGuid = pfGuid;

            frame.SetPixelFormat(ref targetGuid);

            EncodeMetadata(frame, containerFormat, image.Format);

            if (targetGuid != pfGuid)
            {
                // Conversion required to write.
                GCHandle handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned);
                using (var source = new Bitmap(imagingFactory, image.Width, image.Height, pfGuid, new DataRectangle(handle.AddrOfPinnedObject(), image.RowPitch), image.Data.Length))
                {
                    using (var converter = new FormatConverter(imagingFactory))
                    {
                        if (!converter.CanConvert(pfGuid, targetGuid))
                        {
                            throw new NotSupportedException("Format conversion is not supported.");
                        }

                        converter.Initialize(source, targetGuid, GetWicDither(flags), null, 0, BitmapPaletteType.Custom);
                        frame.WriteSource(converter, new Rectangle(0, 0, image.Width, image.Height));
                    }
                }

                handle.Free();
            }
            else
            {
                // No conversion required.
                frame.WritePixels(image.Height, image.RowPitch, image.Data);
            }

            frame.Commit();
        }
Пример #3
0
            private static bool CopyTextureToWICStream(IDeviceResources deviceResource, Texture2D staging, WICStream stream, Guid pfGuid, Guid containerFormat)
            {
                using (var encoder = new BitmapEncoder(deviceResource.WICImgFactory, containerFormat))
                {
                    var desc = staging.Description;
                    encoder.Initialize(stream);
                    var targetGuid = Guid.Empty;
                    using (var frame = new BitmapFrameEncode(encoder))
                    {
                        frame.Initialize();
                        frame.SetSize(desc.Width, desc.Height);
                        frame.SetResolution(72, 72);
                        switch (desc.Format)
                        {
                        case global::SharpDX.DXGI.Format.R32G32B32A32_Float:
                        case global::SharpDX.DXGI.Format.R16G16B16A16_Float:
                            targetGuid = PixelFormat.Format96bppRGBFloat;
                            break;

                        case global::SharpDX.DXGI.Format.R16G16B16A16_UNorm:
                            targetGuid = PixelFormat.Format48bppBGR;
                            break;

                        case global::SharpDX.DXGI.Format.R32_Float:
                        case global::SharpDX.DXGI.Format.R16_Float:
                        case global::SharpDX.DXGI.Format.R16_UNorm:
                        case global::SharpDX.DXGI.Format.R8_UNorm:
                        case global::SharpDX.DXGI.Format.A8_UNorm:
                            targetGuid = PixelFormat.Format48bppBGR;
                            break;

                        default:
                            targetGuid = PixelFormat.Format24bppBGR;
                            break;
                        }
                        frame.SetPixelFormat(ref targetGuid);
                        var databox = deviceResource.Device.ImmediateContext.MapSubresource(staging, 0, MapMode.Read, MapFlags.None);

                        try
                        {
                            if (targetGuid != pfGuid)
                            {
                                using (var bitmap = new Bitmap(deviceResource.WICImgFactory, desc.Width, desc.Height, pfGuid,
                                                               new global::SharpDX.DataRectangle(databox.DataPointer, databox.RowPitch)))
                                {
                                    using (var converter = new FormatConverter(deviceResource.WICImgFactory))
                                    {
                                        if (converter.CanConvert(pfGuid, targetGuid))
                                        {
                                            converter.Initialize(bitmap, targetGuid, BitmapDitherType.None, null, 0, BitmapPaletteType.MedianCut);
                                            frame.WriteSource(converter);
                                        }
                                        else
                                        {
                                            Debug.WriteLine("Cannot convert");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                frame.WritePixels(desc.Height, new global::SharpDX.DataRectangle(databox.DataPointer, databox.RowPitch), databox.RowPitch * desc.Height);
                            }
                        }
                        finally
                        {
                            deviceResource.Device.ImmediateContext.UnmapSubresource(staging, 0);
                        }
                        frame.Commit();
                        encoder.Commit();
                        return(true);
                    }
                }
            }
Пример #4
0
        private Result SaveWicTextureToFileFix(
            DeviceContext context,
            Texture2D source,
            ref Guid guidContainerFormat,
            string fileName)
        {
            if (fileName == null)
            {
                return(Result.InvalidArg);
            }

            var res = CaptureTextureFix(context, source, out var desc, out var staging);

            if (res.Failure)
            {
                return(res);
            }

            Guid pfGuid;
            //bool sRGB = false;
            Guid targetGuid;

            switch (desc.Format)
            {
            case Format.R32G32B32A32_Float: pfGuid = PixelFormat.Format128bppRGBAFloat; break;

            case Format.R16G16B16A16_Float: pfGuid = PixelFormat.Format64bppRGBAHalf; break;

            case Format.R16G16B16A16_UNorm: pfGuid = PixelFormat.Format64bppRGBA; break;

            case Format.R10G10B10_Xr_Bias_A2_UNorm: pfGuid = PixelFormat.Format32bppRGBA1010102XR; break;     // DXGI 1.1

            case Format.R10G10B10A2_UNorm: pfGuid = PixelFormat.Format32bppRGBA1010102; break;

            case Format.B5G5R5A1_UNorm: pfGuid = PixelFormat.Format16bppBGRA5551; break;

            case Format.B5G6R5_UNorm: pfGuid = PixelFormat.Format16bppBGR565; break;

            case Format.R32_Float: pfGuid = PixelFormat.Format32bppGrayFloat; break;

            case Format.R16_Float: pfGuid = PixelFormat.Format16bppGrayHalf; break;

            case Format.R16_UNorm: pfGuid = PixelFormat.Format16bppGray; break;

            case Format.R8_UNorm: pfGuid = PixelFormat.Format8bppGray; break;

            case Format.A8_UNorm: pfGuid = PixelFormat.Format8bppAlpha; break;

            case Format.R8G8B8A8_UNorm:
                pfGuid = PixelFormat.Format32bppRGBA;
                break;

            case Format.R8G8B8A8_UNorm_SRgb:
                pfGuid = PixelFormat.Format32bppRGBA;
                //sRGB = true;
                break;

            case Format.B8G8R8A8_UNorm:     // DXGI 1.1
                pfGuid = PixelFormat.Format32bppBGRA;
                break;

            case Format.B8G8R8A8_UNorm_SRgb:     // DXGI 1.1
                pfGuid = PixelFormat.Format32bppBGRA;
                //sRGB = true;
                break;

            case Format.B8G8R8X8_UNorm:     // DXGI 1.1
                pfGuid = PixelFormat.Format32bppBGR;
                break;

            case Format.B8G8R8X8_UNorm_SRgb:     // DXGI 1.1
                pfGuid = PixelFormat.Format32bppBGR;
                //sRGB = true;
                break;

            default:
                return(Result.GetResultFromWin32Error(unchecked ((int)0x80070032)));
            }

            // Create file
            var fs      = new FileStream(fileName, FileMode.Create);
            var encoder = new BitmapEncoder(Direct2D.ImageFactory, guidContainerFormat);

            encoder.Initialize(fs);


            var frameEncode = new BitmapFrameEncode(encoder);

            frameEncode.Initialize();
            frameEncode.SetSize(desc.Width, desc.Height);
            frameEncode.SetResolution(72.0, 72.0);


            switch (desc.Format)
            {
            case Format.R32G32B32A32_Float:
            case Format.R16G16B16A16_Float:
                targetGuid = PixelFormat.Format24bppBGR;
                break;

            case Format.R16G16B16A16_UNorm: targetGuid = PixelFormat.Format48bppBGR; break;

            case Format.B5G5R5A1_UNorm: targetGuid = PixelFormat.Format16bppBGR555; break;

            case Format.B5G6R5_UNorm: targetGuid = PixelFormat.Format16bppBGR565; break;

            case Format.R32_Float:
            case Format.R16_Float:
            case Format.R16_UNorm:
            case Format.R8_UNorm:
            case Format.A8_UNorm:
                targetGuid = PixelFormat.Format8bppGray;
                break;

            default:
                targetGuid = PixelFormat.Format24bppBGR;
                break;
            }

            frameEncode.SetPixelFormat(ref targetGuid);

            #region Write

            var db = context.MapSubresource(staging, 0, MapMode.Read, MapFlags.None, out _);

            if (pfGuid != targetGuid)
            {
                var formatConverter = new FormatConverter(Direct2D.ImageFactory);

                if (formatConverter.CanConvert(pfGuid, targetGuid))
                {
                    var src = new Bitmap(Direct2D.ImageFactory, desc.Width, desc.Height, pfGuid,
                                         new DataRectangle(db.DataPointer, db.RowPitch));
                    formatConverter.Initialize(src, targetGuid, BitmapDitherType.None, null, 0, BitmapPaletteType.Custom);
                    frameEncode.WriteSource(formatConverter, new Rectangle(0, 0, desc.Width, desc.Height));
                }
            }
            else
            {
                frameEncode.WritePixels(desc.Height, new DataRectangle(db.DataPointer, db.RowPitch));
            }

            context.UnmapSubresource(staging, 0);

            frameEncode.Commit();
            encoder.Commit();

            #endregion

            frameEncode.Dispose();
            encoder.Dispose();

            fs.Close();

            return(Result.Ok);
        }
Пример #5
0
        /// <summary>
        /// 從WIC Frame建立貼圖資源(非DDS)
        /// </summary>
        /// <param name="d3dContext">If a Direct3D 11 device context is provided and the current device supports it for the given pixel format, it will auto-generate mipmaps.</param>
        private static Result CreateWICTexture(Device device, DeviceContext d3dContext, BitmapFrameDecode frame, int maxsize, ResourceUsage usage, BindFlags bind, CpuAccessFlags cpuAccess, ResourceOptionFlags option, LoadFlags load, out Resource texture, out ShaderResourceView textureView)
        {
            texture     = null;
            textureView = null;

            if (frame.Size.Width <= 0 || frame.Size.Height <= 0)
            {
                return(Result.InvalidArg);
            }

            if (maxsize == 0)
            {
                switch (device.FeatureLevel)
                {
                case FeatureLevel.Level_9_1:
                case FeatureLevel.Level_9_2:
                    maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
                    break;

                case FeatureLevel.Level_9_3:
                    maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
                    break;

                case FeatureLevel.Level_10_0:
                case FeatureLevel.Level_10_1:
                    maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
                    break;

                default:
                    maxsize = Resource.MaximumTexture2DSize;     /*D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION*/
                    break;
                }
            }

            Size2 frameSize = frame.Size;
            Size2 targetSize;

            if (frameSize.Width > maxsize || frameSize.Height > maxsize)
            {
                double ratio = Convert.ToDouble(frameSize.Height) / Convert.ToDouble(frameSize.Width);
                if (frameSize.Width > frameSize.Height)
                {
                    targetSize.Width  = maxsize;
                    targetSize.Height = Math.Max(1, Convert.ToInt32(maxsize * ratio));
                }
                else
                {
                    targetSize.Height = maxsize;
                    targetSize.Width  = Math.Max(1, Convert.ToInt32(maxsize / ratio));
                }
            }
            else
            {
                targetSize = frameSize;
            }

            #region Determine format
            Guid        sourceFormat = frame.PixelFormat;
            Guid        targetFormat = sourceFormat;
            DXGI.Format format       = sourceFormat.ConvertWICToDXGIFormat();
            int         bpp          = 0;

            if (format == DXGI.Format.Unknown)
            {
                if (sourceFormat == PixelFormat.Format96bppRGBFixedPoint)
                {
                    if (WIC2)
                    {
                        targetFormat = PixelFormat.Format96bppRGBFloat;
                        format       = DXGI.Format.R32G32B32_Float;
                        bpp          = 96;
                    }
                    else
                    {
                        targetFormat = PixelFormat.Format128bppRGBAFloat;
                        format       = DXGI.Format.R32G32B32A32_Float;
                        bpp          = 128;
                    }
                }
                else
                {
                    targetFormat = sourceFormat.ConvertToNearest();
                    format       = targetFormat.ConvertWICToDXGIFormat();
                    bpp          = PixelFormat.GetBitsPerPixel(targetFormat);
                }
                if (format == DXGI.Format.Unknown)
                {
                    return(Result.GetResultFromWin32Error(unchecked ((int)0x80070032)));
                }
            }
            else
            {
                bpp = PixelFormat.GetBitsPerPixel(sourceFormat);
            }

            if (format == DXGI.Format.R32G32B32_Float && d3dContext != null)
            {
                // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT
                var formatSupport = device.CheckFormatSupport(format);
                if (!formatSupport.HasFlag(FormatSupport.MipAutogen))
                {
                    targetFormat = PixelFormat.Format128bppRGBAFloat;
                    format       = DXGI.Format.R32G32B32A32_Float;
                    bpp          = 128;
                }
            }
            if (bpp == 0)
            {
                return(Result.Fail);
            }

            if (load.HasFlag(LoadFlags.ForceSrgb))
            {
                format = format.MakeSRgb();
            }
            else if (!load.HasFlag(LoadFlags.ignoreSrgb))
            {
                bool sRGB = false;
                try {
                    var metareader      = frame.MetadataQueryReader;
                    var containerFormat = metareader.ContainerFormat;

                    if (containerFormat == ContainerFormatGuids.Png)
                    {
                        // Check for sRGB chunk
                        if (metareader.TryGetMetadataByName("/sRGB/RenderingIntent", out var value) == Result.Ok)
                        {
                            sRGB = true;
                        }
                    }
                    else if (metareader.TryGetMetadataByName("System.Image.ColorSpace", out var value) == Result.Ok)
                    {
                        sRGB = true;
                    }

                    if (sRGB)
                    {
                        format = format.MakeSRgb();
                    }
                } catch (SharpDXException) {
                    // BMP, ICO are not supported.
                }
            }

            // Verify our target format is supported by the current device
            var support = device.CheckFormatSupport(format);
            if (!support.HasFlag(FormatSupport.Texture2D))
            {
                targetFormat = PixelFormat.Format32bppRGBA;
                format       = DXGI.Format.R8G8B8A8_UNorm;
                bpp          = 32;
            }
            #endregion


            int    stride    = (targetSize.Width * bpp + 7) / 8; // round
            int    imageSize = stride * targetSize.Height;
            IntPtr temp      = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(imageSize);

            if (sourceFormat == targetFormat && frameSize == targetSize)   // 不需要格式轉換 且 不需要改變大小
            {
                frame.CopyPixels(stride, new DataPointer(temp, imageSize));
            }
            else if (frameSize == targetSize)     // 需要格式轉換
            {
                using (var factory = new ImagingFactory2())
                    using (var coverter = new FormatConverter(factory)) {
                        if (coverter.CanConvert(sourceFormat, targetFormat))
                        {
                            coverter.Initialize(frame, targetFormat, BitmapDitherType.ErrorDiffusion, null, 0, BitmapPaletteType.MedianCut);
                            coverter.CopyPixels(stride, new DataPointer(temp, imageSize));
                        }
                        else
                        {
                            return(Result.UnexpectedFailure);
                        }
                    }
            }
            else if (sourceFormat == targetFormat)     // 需要改變大小
            {
                using (var factory = new ImagingFactory2())
                    using (var scaler = new BitmapScaler(factory)) {
                        scaler.Initialize(frame, targetSize.Width, targetSize.Height, BitmapInterpolationMode.Fant);
                        var pfScaler = scaler.PixelFormat;
                        if (targetFormat == pfScaler)
                        {
                            scaler.CopyPixels(stride, new DataPointer(temp, imageSize));
                        }
                    }
            }
            else     // 需要格式轉換 且 需要改變大小
            {
                using (var factory = new ImagingFactory2())
                    using (var scaler = new BitmapScaler(factory))
                        using (var coverter = new FormatConverter(factory)) {
                            scaler.Initialize(frame, targetSize.Width, targetSize.Height, BitmapInterpolationMode.Fant);
                            var pfScaler = scaler.PixelFormat;

                            if (coverter.CanConvert(pfScaler, targetFormat))
                            {
                                coverter.Initialize(scaler, targetFormat, BitmapDitherType.ErrorDiffusion, null, 0, BitmapPaletteType.MedianCut);
                                coverter.CopyPixels(stride, new DataPointer(temp, imageSize));
                            }
                            else
                            {
                                return(Result.UnexpectedFailure);
                            }
                        }
            }

            var autogen = false;

            if (d3dContext != null)
            {
                var formatSupport = device.CheckFormatSupport(format);
                if (formatSupport.HasFlag(FormatSupport.MipAutogen))
                {
                    autogen = true;
                }
            }

            var texture2DDescription = new Texture2DDescription()
            {
                Width             = targetSize.Width,
                Height            = targetSize.Height,
                MipLevels         = autogen ? 0 : 1,
                ArraySize         = 1,
                Format            = format,
                SampleDescription = new DXGI.SampleDescription(1, 0),
                Usage             = usage,
                CpuAccessFlags    = cpuAccess,
            };

            if (autogen)
            {
                texture2DDescription.BindFlags   = bind | BindFlags.RenderTarget;
                texture2DDescription.OptionFlags = option | ResourceOptionFlags.GenerateMipMaps;
            }
            else
            {
                texture2DDescription.BindFlags   = bind;
                texture2DDescription.OptionFlags = option;
            }

            Result result = Result.Ok;

            // 建立Texture2D !!!
            try {
                if (autogen)
                {
                    texture = new Texture2D(device, texture2DDescription);
                }
                else
                {
                    texture = new Texture2D(device, texture2DDescription, new DataBox[] { new DataBox(temp, stride, imageSize) });
                }
            } catch (SharpDXException e) {
                System.Diagnostics.Debug.WriteLine(e.ToString());
                result = Result.Fail;
            }

            if (result.Success)
            {
                var SRVDesc = new ShaderResourceViewDescription()
                {
                    Format    = format,
                    Dimension = ShaderResourceViewDimension.Texture2D,
                    Texture2D = new ShaderResourceViewDescription.Texture2DResource()
                    {
                        MipLevels = autogen ? -1 : 1
                    },
                };

                try {
                    textureView = new ShaderResourceView(device, texture, SRVDesc);
                    if (autogen)
                    {
                        DataBox data = new DataBox(temp, stride, imageSize);
                        d3dContext.UpdateSubresource(data, texture);
                        d3dContext.GenerateMips(textureView);
                    }
                } catch (Exception e) {
                    System.Diagnostics.Debug.WriteLine(e.ToString());
                    Utilities.Dispose(ref texture);
                    result = Result.Fail;
                }
            }

            // 釋放 Unmanaged 資源
            System.Runtime.InteropServices.Marshal.FreeCoTaskMem(temp);

            return(result);
        }
Пример #6
0
        public static Result SaveTextureToStream(Device d3dDevice, Resource source, Stream stream, Guid containerFormat, Guid targetFormatGuid)
        {
            Result result = Result.Fail;

            if (source == null || d3dDevice == null || stream == null)
            {
                return(Result.InvalidArg);
            }
            result = CreateStagingTexture(d3dDevice.ImmediateContext, source, out Texture2DDescription desc, out Texture2D staging);
            if (!result.Success)
            {
                return(result);
            }

            Guid sourceFormat = desc.Format.ConvertDXGIToWICFormat();

            if (sourceFormat == Guid.Empty)
            {
                return(Result.InvalidArg);
            }

            if (ImagingFactory == null)
            {
                return(Result.NoInterface);
            }

            Guid targetFormat = targetFormatGuid;

            if (targetFormat == Guid.Empty)
            {
                switch (desc.Format)
                {
                case DXGI.Format.R32G32B32A32_Float:
                case DXGI.Format.R16G16B16A16_Float:
                    if (WIC2)
                    {
                        targetFormat = PixelFormat.Format96bppRGBFloat;
                    }
                    else
                    {
                        targetFormat = PixelFormat.Format24bppBGR;
                    }
                    break;

                case DXGI.Format.R16G16B16A16_UNorm:
                    targetFormat = PixelFormat.Format48bppBGR;
                    break;

                case DXGI.Format.B5G5R5A1_UNorm:
                    targetFormat = PixelFormat.Format16bppBGR555;
                    break;

                case DXGI.Format.B5G6R5_UNorm:
                    targetFormat = PixelFormat.Format16bppBGR565;
                    break;

                case DXGI.Format.R32_Float:
                case DXGI.Format.R16_Float:
                case DXGI.Format.R16_UNorm:
                case DXGI.Format.R8_UNorm:
                case DXGI.Format.A8_UNorm:
                    targetFormat = PixelFormat.Format8bppGray;
                    break;

                default:
                    targetFormat = PixelFormat.Format24bppBGR;
                    break;
                }
            }

            if (targetFormatGuid != Guid.Empty && targetFormatGuid != targetFormat)
            {
                return(result);
            }

            try {
                // Create a new file
                if (stream.CanWrite)
                {
                    using (BitmapEncoder encoder = new BitmapEncoder(ImagingFactory, containerFormat)) {
                        encoder.Initialize(stream);

                        using (BitmapFrameEncode frameEncode = new BitmapFrameEncode(encoder)) {
                            frameEncode.Initialize();
                            frameEncode.SetSize(desc.Width, desc.Height);
                            frameEncode.SetResolution(72.0, 72.0);


                            frameEncode.SetPixelFormat(ref targetFormat);

                            if (targetFormatGuid == Guid.Empty || targetFormat == targetFormatGuid)
                            {
                                int subresource = 0;

                                // 讓CPU存取顯存貼圖
                                // MapSubresource 在 deferred context 下不支援 MapMode.Read
                                DataBox db = d3dDevice.ImmediateContext.MapSubresource(staging, subresource, MapMode.Read, MapFlags.None, out var dataStream);

                                if (sourceFormat != targetFormat)
                                {
                                    // BGRA格式轉換
                                    using (FormatConverter formatCoverter = new FormatConverter(ImagingFactory)) {
                                        if (formatCoverter.CanConvert(sourceFormat, targetFormat))
                                        {
                                            Bitmap src = new Bitmap(ImagingFactory, desc.Width, desc.Height, sourceFormat, new DataRectangle(db.DataPointer, db.RowPitch));
                                            formatCoverter.Initialize(src, targetFormat, BitmapDitherType.None, null, 0, BitmapPaletteType.Custom);
                                            frameEncode.WriteSource(formatCoverter, new Rectangle(0, 0, desc.Width, desc.Height));
                                        }
                                    }
                                }
                                else
                                {
                                    frameEncode.WritePixels(desc.Height, new DataRectangle(db.DataPointer, db.RowPitch));
                                }

                                // 控制權歸還
                                d3dDevice.ImmediateContext.UnmapSubresource(staging, subresource);

                                frameEncode.Commit();
                                encoder.Commit();
                                result = Result.Ok;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                System.Diagnostics.Debug.WriteLine(e.ToString());
                result = Result.Fail;
            }

            Utilities.Dispose(ref staging);

            return(result);
        }