示例#1
0
        //-------------------------------------------------------------------------------------
        // Encodes a single frame
        //-------------------------------------------------------------------------------------
        private static void EncodeImage(PixelBuffer image, WICFlags flags, BitmapFrameEncode frame)
        {
            Guid pfGuid;

            if (!ToWIC(image.Format, out pfGuid))
            {
                throw new NotSupportedException("Format not supported");
            }

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

            frame.SetPixelFormat(ref targetGuid);

            if (targetGuid != pfGuid)
            {
                using (var source = new Bitmap(Factory, image.Width, image.Height, pfGuid, new DataRectangle(image.DataPointer, image.RowStride), image.BufferStride))
                {
                    using (var converter = new FormatConverter(Factory))
                    {
                        using (var palette = new Palette(Factory))
                        {
                            palette.Initialize(source, 256, true);
                            converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, BitmapPaletteType.Custom);

                            int bpp = GetBitsPerPixel(targetGuid);
                            if (bpp == 0)
                            {
                                throw new NotSupportedException("Unable to determine the Bpp for the target format");
                            }

                            int rowPitch   = (image.Width * bpp + 7) / 8;
                            int slicePitch = rowPitch * image.Height;

                            var temp = Utilities.AllocateMemory(slicePitch);
                            try
                            {
                                converter.CopyPixels(rowPitch, temp, slicePitch);
                                frame.Palette = palette;
                                frame.WritePixels(image.Height, temp, rowPitch, slicePitch);
                            }
                            finally
                            {
                                Utilities.FreeMemory(temp);
                            }
                        }
                    }
                }
            }
            else
            {
                // No conversion required
                frame.WritePixels(image.Height, image.DataPointer, image.RowStride, image.BufferStride);
            }

            frame.Commit();
        }
示例#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
        //-------------------------------------------------------------------------------------
        // Encodes a single frame
        //-------------------------------------------------------------------------------------
        private static void EncodeImage( PixelBuffer image, WICFlags flags, BitmapFrameEncode frame)
        {
            Guid pfGuid;
            if (! ToWIC(image.Format, out pfGuid))
                throw new NotSupportedException("Format not supported");

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

            if (targetGuid != pfGuid)
            {
                using (var source = new Bitmap(Factory, image.Width, image.Height, pfGuid, new DataRectangle(image.DataPointer, image.RowStride), image.BufferStride))
                {
                    using (var converter = new FormatConverter(Factory))
                    {
                        using (var palette = new Palette(Factory))
                        {
                            palette.Initialize(source, 256, true);
                            converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, BitmapPaletteType.Custom);

                            int bpp = GetBitsPerPixel(targetGuid);
                            if (bpp == 0) throw new NotSupportedException("Unable to determine the Bpp for the target format");

                            int rowPitch = (image.Width * bpp + 7) / 8;
                            int slicePitch = rowPitch * image.Height;

                            var temp = Utilities.AllocateMemory(slicePitch);
                            try
                            {
                                converter.CopyPixels(rowPitch, temp, slicePitch);
                                frame.Palette = palette;
                                frame.WritePixels(image.Height, temp, rowPitch, slicePitch);
                            }
                            finally
                            {
                                Utilities.FreeMemory(temp);
                            }
                        }
                    }
                }
            }
            else
            {
                // No conversion required
                frame.WritePixels(image.Height, image.DataPointer, image.RowStride, image.BufferStride);
            }

            frame.Commit();
        }
            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);
                    }
                }
            }
示例#5
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();
        }
示例#6
0
        private static void FlushCurrentFrame(GifBitmapEncoder encoder,
            ImagingFactory factory,
            BitmapFrame bitmap)
        {
            // nothing to flush.
            if (bitmap == null)
            {
                return;
            }

            using (var frameEncoder = new BitmapFrameEncode(encoder))
            {
                frameEncoder.Initialize();
                frameEncoder.SetSize(bitmap.Data.Width, bitmap.Data.Height);
                frameEncoder.SetResolution(bitmap.Data.HorizontalResolution, bitmap.Data.VerticalResolution);

                // embed frame metadata.
                var metadataWriter = frameEncoder.MetadataQueryWriter;
                metadataWriter.SetMetadataByName("/grctlext/Delay", Convert.ToUInt16(bitmap.Delay/100));
                metadataWriter.SetMetadataByName("/imgdesc/Left", Convert.ToUInt16(bitmap.XPos));
                metadataWriter.SetMetadataByName("/imgdesc/Top", Convert.ToUInt16(bitmap.YPos));
                metadataWriter.SetMetadataByName("/imgdesc/Width", Convert.ToUInt16(bitmap.Data.Width));
                metadataWriter.SetMetadataByName("/imgdesc/Height", Convert.ToUInt16(bitmap.Data.Height));

                using (var bitmapSource = new WicBitmap(
                    factory,
                    bitmap.Data,
                    BitmapAlphaChannelOption.UsePremultipliedAlpha))
                {
                    var converter = new FormatConverter(factory);
                    converter.Initialize(bitmapSource,
                        PixelFormat.Format8bppIndexed,
                        BitmapDitherType.Solid,
                        null,
                        0.8,
                        BitmapPaletteType.MedianCut);

                    frameEncoder.WriteSource(converter);
                    frameEncoder.Commit();
                }
            }
        }
示例#7
0
        /// <summary>
        /// Saves a texture to a stream as an image.
        /// </summary>
        /// <param name="texture">The texture to save.</param>
        /// <param name="imageFormat">The image format of the saved image.</param>
        /// <param name="imageResolutionInDpi">The image resolution in dpi.</param>
        /// <param name="toStream">The stream to save the texture to.</param>
        public static void SaveToStream(this Texture2D texture, System.Drawing.Imaging.ImageFormat imageFormat, double imageResolutionInDpi, System.IO.Stream toStream)
        {
            Texture2D      textureCopy    = null;
            ImagingFactory imagingFactory = null;
            Bitmap         bitmap         = null;
            BitmapEncoder  bitmapEncoder  = null;

            try
            {
                textureCopy = new Texture2D(texture.Device, new Texture2DDescription
                {
                    Width             = texture.Description.Width,
                    Height            = texture.Description.Height,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    Format            = texture.Description.Format,
                    Usage             = ResourceUsage.Staging,
                    SampleDescription = new SampleDescription(1, 0),
                    BindFlags         = BindFlags.None,
                    CpuAccessFlags    = CpuAccessFlags.Read,
                    OptionFlags       = ResourceOptionFlags.None
                });

                texture.Device.CopyResource(texture, textureCopy);

                DataRectangle dataRectangle = textureCopy.Map(0, MapMode.Read, SharpDX.Direct3D10.MapFlags.None);

                imagingFactory = new ImagingFactory();
                bitmap         = new Bitmap(
                    imagingFactory,
                    textureCopy.Description.Width,
                    textureCopy.Description.Height,
                    PixelFormat.Format32bppBGRA,
                    dataRectangle);

                toStream.Position = 0;

                if (imageFormat == System.Drawing.Imaging.ImageFormat.Png)
                {
                    bitmapEncoder = new PngBitmapEncoder(imagingFactory, toStream);
                }
                else if (imageFormat == System.Drawing.Imaging.ImageFormat.Bmp)
                {
                    bitmapEncoder = new BmpBitmapEncoder(imagingFactory, toStream);
                }
                else if (imageFormat == System.Drawing.Imaging.ImageFormat.Gif)
                {
                    bitmapEncoder = new GifBitmapEncoder(imagingFactory, toStream);
                }
                else if (imageFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
                {
                    bitmapEncoder = new JpegBitmapEncoder(imagingFactory, toStream);
                }
                else if (imageFormat == System.Drawing.Imaging.ImageFormat.Tiff)
                {
                    bitmapEncoder = new TiffBitmapEncoder(imagingFactory, toStream);
                }
                else
                {
                    bitmapEncoder = new PngBitmapEncoder(imagingFactory, toStream);
                }

                using (var bitmapFrameEncode = new BitmapFrameEncode(bitmapEncoder))
                {
                    bitmapFrameEncode.Initialize();
                    bitmapFrameEncode.SetSize(bitmap.Size.Width, bitmap.Size.Height);
                    var pixelFormat = PixelFormat.FormatDontCare;
                    bitmapFrameEncode.SetPixelFormat(ref pixelFormat);
                    bitmapFrameEncode.SetResolution(imageResolutionInDpi, imageResolutionInDpi);
                    bitmapFrameEncode.WriteSource(bitmap);
                    bitmapFrameEncode.Commit();
                    bitmapEncoder.Commit();
                }
            }
            finally
            {
                bitmapEncoder?.Dispose();
                textureCopy?.Unmap(0);
                textureCopy?.Dispose();
                bitmap?.Dispose();
                imagingFactory?.Dispose();
            }
        }
示例#8
0
		/// <summary>
		/// Saves a texture to a stream as an image.
		/// </summary>
		/// <param name="texture">The texture to save.</param>
		/// <param name="imageFormat">The image format of the saved image.</param>
		/// <param name="imageResolutionInDpi">The image resolution in dpi.</param>
		/// <param name="toStream">The stream to save the texture to.</param>
		public static void SaveToStream(this Texture2D texture, System.Drawing.Imaging.ImageFormat imageFormat, double imageResolutionInDpi, System.IO.Stream toStream)
		{
			Texture2D textureCopy = null;
			ImagingFactory imagingFactory = null;
			Bitmap bitmap = null;
			BitmapEncoder bitmapEncoder = null;

			try
			{
				textureCopy = new Texture2D(texture.Device, new Texture2DDescription
				{
					Width = (int)texture.Description.Width,
					Height = (int)texture.Description.Height,
					MipLevels = 1,
					ArraySize = 1,
					Format = texture.Description.Format,
					Usage = ResourceUsage.Staging,
					SampleDescription = new SampleDescription(1, 0),
					BindFlags = BindFlags.None,
					CpuAccessFlags = CpuAccessFlags.Read,
					OptionFlags = ResourceOptionFlags.None
				});

				texture.Device.CopyResource(texture, textureCopy);

				DataRectangle dataRectangle = textureCopy.Map(0, MapMode.Read, SharpDX.Direct3D10.MapFlags.None);

				imagingFactory = new ImagingFactory();
				bitmap = new Bitmap(
						imagingFactory,
						textureCopy.Description.Width,
						textureCopy.Description.Height,
						PixelFormat.Format32bppBGRA,
						dataRectangle);

				toStream.Position = 0;

				if (imageFormat == System.Drawing.Imaging.ImageFormat.Png)
					bitmapEncoder = new PngBitmapEncoder(imagingFactory, toStream);
				else if (imageFormat == System.Drawing.Imaging.ImageFormat.Bmp)
					bitmapEncoder = new BmpBitmapEncoder(imagingFactory, toStream);
				else if (imageFormat == System.Drawing.Imaging.ImageFormat.Gif)
					bitmapEncoder = new GifBitmapEncoder(imagingFactory, toStream);
				else if (imageFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
					bitmapEncoder = new JpegBitmapEncoder(imagingFactory, toStream);
				else if (imageFormat == System.Drawing.Imaging.ImageFormat.Tiff)
					bitmapEncoder = new TiffBitmapEncoder(imagingFactory, toStream);
				else
					bitmapEncoder = new PngBitmapEncoder(imagingFactory, toStream);

				using (var bitmapFrameEncode = new BitmapFrameEncode(bitmapEncoder))
				{
					bitmapFrameEncode.Initialize();
					bitmapFrameEncode.SetSize(bitmap.Size.Width, bitmap.Size.Height);
					var pixelFormat = PixelFormat.FormatDontCare;
					bitmapFrameEncode.SetPixelFormat(ref pixelFormat);
					bitmapFrameEncode.SetResolution(imageResolutionInDpi, imageResolutionInDpi);
					bitmapFrameEncode.WriteSource(bitmap);
					bitmapFrameEncode.Commit();
					bitmapEncoder.Commit();
				}
			}
			finally
			{
				bitmapEncoder?.Dispose();
				textureCopy?.Unmap(0);
				textureCopy?.Dispose();
				bitmap?.Dispose();
				imagingFactory?.Dispose();
			}
		}
示例#9
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);
        }
示例#10
0
        /// <summary>
        /// Function to persist image data to a stream.
        /// </summary>
        /// <param name="imageData"><see cref="GorgonLibrary.Graphics.GorgonImageData">Gorgon image data</see> to persist.</param>
        /// <param name="stream">Stream that will contain the data.</param>
        protected internal override void SaveToStream(GorgonImageData imageData, Stream stream)
        {
            int frameCount = 1;

            // Wrap the stream so WIC doesn't mess up the position.
            using (var wrapperStream = new GorgonStreamWrapper(stream))
            {
                using (var wic = new GorgonWICImage())
                {
                    // Find a compatible format.
                    Guid targetFormat = wic.GetGUID(imageData.Settings.Format);

                    if (targetFormat == Guid.Empty)
                    {
                        throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, imageData.Settings.Format));
                    }

                    Guid actualFormat = targetFormat;

                    using (var encoder = new BitmapEncoder(wic.Factory, SupportedFormat))
                    {
                        try
                        {
                            encoder.Initialize(wrapperStream);
                            AddCustomMetaData(encoder, null, 0, imageData.Settings, null);
                        }
                        catch (SharpDXException)
                        {
                            // Repackage this exception to keep in line with our API.
                            throw new IOException(string.Format(Resources.GORGFX_IMAGE_FILE_INCORRECT_ENCODER, Codec));
                        }

                        using (var encoderInfo = encoder.EncoderInfo)
                        {
                            if ((imageData.Settings.ArrayCount > 1) && (CodecUseAllFrames) && (encoderInfo.IsMultiframeSupported))
                            {
                                frameCount = imageData.Settings.ArrayCount;
                            }

                            for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                            {
                                using (var frame = new BitmapFrameEncode(encoder))
                                {
                                    var buffer = imageData.Buffers[0, frameIndex];

                                    frame.Initialize();
                                    frame.SetSize(buffer.Width, buffer.Height);
                                    frame.SetResolution(72, 72);
                                    frame.SetPixelFormat(ref actualFormat);

                                    SetFrameOptions(frame);

                                    // If the image encoder doesn't like the format we've chosen, then we'll need to convert to
                                    // the best format for the codec.
                                    if (targetFormat != actualFormat)
                                    {
                                        var rect = new DataRectangle(buffer.Data.BasePointer, buffer.PitchInformation.RowPitch);
                                        using (var bitmap = new Bitmap(wic.Factory, buffer.Width, buffer.Height, targetFormat, rect))
                                        {
                                            // If we're using a codec that supports 8 bit indexed data, then get the palette info.
                                            var paletteInfo = GetPaletteInfo(wic, bitmap);

                                            if (paletteInfo == null)
                                            {
                                                throw new IOException(string.Format(Resources.GORGFX_IMAGE_FILE_INCORRECT_ENCODER, Codec));
                                            }

                                            try
                                            {
                                                using (var converter = new FormatConverter(wic.Factory))
                                                {
                                                    converter.Initialize(bitmap, actualFormat, (BitmapDitherType)Dithering, paletteInfo.Item1, paletteInfo.Item2, paletteInfo.Item3);
                                                    if (paletteInfo.Item1 != null)
                                                    {
                                                        frame.Palette = paletteInfo.Item1;
                                                    }

                                                    AddCustomMetaData(encoder, frame, frameIndex, imageData.Settings, (paletteInfo.Item1 != null) ? paletteInfo.Item1.Colors : null);
                                                    frame.WriteSource(converter);
                                                }
                                            }
                                            finally
                                            {
                                                if (paletteInfo.Item1 != null)
                                                {
                                                    paletteInfo.Item1.Dispose();
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // No conversion was needed, just dump as-is.
                                        AddCustomMetaData(encoder, frame, frameIndex, imageData.Settings, null);
                                        frame.WritePixels(buffer.Height, buffer.Data.BasePointer, buffer.PitchInformation.RowPitch, buffer.PitchInformation.SlicePitch);
                                    }

                                    frame.Commit();
                                }
                            }
                        }

                        encoder.Commit();
                    }
                }
            }
        }
示例#11
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);
        }