Esempio n. 1
0
        private bool CheckConvertion(MainForm form, IWICFormatConverterInfo info, Guid from, Guid to)
        {
            if (from == to)
            {
                return(true);
            }

            IWICImagingFactory factory = (IWICImagingFactory) new WICImagingFactory();
            IWICPalette        palette = factory.CreatePalette();

            palette.InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedBW, false);
            IWICBitmap          bitmap    = null;
            IWICFormatConverter converter = null;

            try
            {
                try
                {
                    converter = info.CreateInstance();
                }
                catch (Exception e)
                {
                    form.Add(this, e.TargetSite.ToString(Resources._0_Failed), new DataEntry(e));

                    return(false);
                }

                try
                {
                    bitmap = factory.CreateBitmap(1, 1, from, WICBitmapCreateCacheOption.WICBitmapCacheOnLoad);
                    bitmap.SetPalette(palette);
                }
                catch (Exception e)
                {
                    form.Add(this, e.TargetSite.ToString(Resources._0_Failed), new DataEntry(e), new DataEntry(Resources.PixelFormat, from));

                    return(false);
                }

                try
                {
                    converter.Initialize(bitmap, to, WICBitmapDitherType.WICBitmapDitherTypeNone, palette, 0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                }
                catch (Exception e)
                {
                    form.CheckHRESULT(this, WinCodecError.WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, e, new DataEntry(Resources.Source, from), new DataEntry(Resources.Destination, to));

                    return(false);
                }

                return(true);
            }
            finally
            {
                palette.ReleaseComObject();
                converter.ReleaseComObject();
                bitmap.ReleaseComObject();
                factory.ReleaseComObject();
            }
        }
Esempio n. 2
0
 public static IWICBitmapLock Lock(this IWICBitmap bitmap, WICBitmapLockFlags flags, WICRect?prcLock = null)
 {
     using (var prcLockPtr = CoTaskMemPtr.From(prcLock))
     {
         return(bitmap.Lock(prcLockPtr, flags));
     }
 }
Esempio n. 3
0
 public extern static void CreateBitmapFromSection(
     uint width,
     uint height,
     [ComAliasName("REFWICPixelFormatGUID")]
     [In] Guid pixelFormat,
     IntPtr hSection,
     uint stride,
     uint offset,
     [Out] out IWICBitmap pIBitmap
     );
Esempio n. 4
0
        public static IComObject <IWICBitmapLock> Lock(this IWICBitmap bitmap, WICBitmapLockFlags flags, WICRect?rect = null)
        {
            if (bitmap == null)
            {
                throw new ArgumentNullException(nameof(bitmap));
            }

            using (var mem = new ComMemory(rect))
            {
                bitmap.Lock(mem.Pointer, flags, out var value).ThrowOnError();
                return(new ComObject <IWICBitmapLock>(value));
            }
        }
Esempio n. 5
0
        public static IWICBitmap CaptureMobileScreenshot()
        {
            var ppBitmap = new IWICBitmap[1];
            var num      = NativeMethods.CaptureScreen(dwFlags: 0U, ppBitmap: ppBitmap);

            if (num != 0)
            {
                var lastWin32Error = Marshal.GetLastWin32Error();
                throw new DisplayException(message: string.Format(format: "CaptureScreen failed with result: {0} and error: {1}", arg0: num, arg1: lastWin32Error));
            }

            Log.Out(msg: "CaptureScreen succeeded with result: {0}", (object)num);
            return(ppBitmap[0]);
        }
Esempio n. 6
0
        public static IWICBitmap ToWic(IWICComponentFactory factory, Bitmap bit)
        {
            Guid pixelFormat = ConversionUtils.FromPixelFormat(bit.PixelFormat);

            if (pixelFormat == Guid.Empty)
            {
                throw new NotSupportedException("PixelFormat " + bit.PixelFormat.ToString() + " not supported.");
            }
            BitmapData  bd = bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height), ImageLockMode.ReadOnly, bit.PixelFormat);
            IWICBitmap  b  = null;
            IWICPalette p  = null;

            try {
                //Create WIC bitmap directly from unmanaged memory
                long result = CreateBitmapFromMemory(factory, (uint)bit.Width, (uint)bit.Height, ref pixelFormat, (uint)bd.Stride, (uint)(bd.Stride * bd.Height), bd.Scan0, out b);
                //b = factory.CreateBitmapFromMemory((uint)bit.Width, (uint)bit.Height, ConversionUtils.FromPixelFormat(bit.PixelFormat), (uint)bd.Stride, (uint)(bd.Stride * bd.Height), bd.Scan0);
                if (result == 0x80070057)
                {
                    throw new ArgumentException();
                }
                if (result < 0)
                {
                    throw new Exception("HRESULT " + result);
                }

                //Copy the bitmap palette if it exists
                var sPalette = bit.Palette;
                if (sPalette.Entries.Length > 0)
                {
                    p = factory.CreatePalette();
                    uint[] colors = new uint[sPalette.Entries.Length];
                    for (int i = 0; i < sPalette.Entries.Length; i++)
                    {
                        colors[i] = (uint)(((sPalette.Entries[i].A << 24) | (sPalette.Entries[i].R << 16) | (sPalette.Entries[i].G << 8) | sPalette.Entries[i].B) & 0xffffffffL);
                    }
                    p.InitializeCustom(colors, (uint)colors.Length);
                    b.SetPalette(p);
                }

                return(b);
            } finally {
                bit.UnlockBits(bd);
                if (p != null)
                {
                    Marshal.ReleaseComObject(p);
                }
            }
        }
Esempio n. 7
0
        public static void SaveD2DBitmap(IWICImagingFactory wic, IWICBitmap wicBitmap, Stream outputStream)
        {
            using (IWICBitmapEncoder encoder = wic.CreateEncoder(ContainerFormat.Png))
            {
                encoder.Initialize(outputStream);
                using (IWICBitmapFrameEncode frame = encoder.CreateNewFrame(out IPropertyBag2 props))
                {
                    frame.Initialize();
                    frame.SetSize(wicBitmap.Size.Width, wicBitmap.Size.Height);

                    var pixelFormat = wicBitmap.PixelFormat;
                    frame.SetPixelFormat(ref pixelFormat);
                    frame.WriteSource(wicBitmap);

                    frame.Commit();
                    encoder.Commit();
                }
            }
        }
Esempio n. 8
0
        protected override bool ProcessEncoder(MainForm form, IWICBitmapEncoder encoder, object tag)
        {
            IWICImagingFactory factory = (IWICImagingFactory) new WICImagingFactory();
            IWICBitmap         bitmap  = factory.CreateBitmap(16, 16, Consts.GUID_WICPixelFormat32bppBGRA, WICBitmapCreateCacheOption.WICBitmapCacheOnLoad);
            IWICPalette        palette = factory.CreatePalette();

            palette.InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedBW, false);
            IWICColorContext context = factory.CreateColorContext();

            context.InitializeFromExifColorSpace(ExifColorSpace.sRGB);

            ComponentInfoHelper.CheckEquals <IWICBitmapEncoderInfo>(form, encoder.GetEncoderInfo, this, Extensions.CompareInfos);
            Check(form, encoder.SetPalette, palette);
            Check(form, encoder.SetThumbnail, bitmap);
            Check(form, encoder.SetPreview, bitmap);
            try
            {
                encoder.SetColorContexts(1, new IWICColorContext[] { context });
            }
            catch (Exception e)
            {
                form.CheckHRESULT(this, WinCodecError.WINCODEC_ERR_UNSUPPORTEDOPERATION, e);
            }

            try
            {
                encoder.Commit();
                form.Add(this, string.Format(CultureInfo.CurrentUICulture, Resources._0_ShouldFail, "IWICBitmapEncoder::Commit(...)"), new DataEntry(Resources.FrameCount, 0));
            }
            catch (Exception e)
            {
                form.CheckHRESULT(this, WinCodecError.WINCODEC_ERR_FRAMEMISSING, e, new DataEntry(Resources.FrameCount, 0));
            }

            palette.ReleaseComObject();
            bitmap.ReleaseComObject();
            factory.ReleaseComObject();
            context.ReleaseComObject();

            return(base.ProcessEncoder(form, encoder, tag));
        }
Esempio n. 9
0
        public void Write(System.Drawing.Image i, System.IO.Stream s)
        {
            //A list of COM objects to destroy
            List <object> com = new List <object>();

            try {
                var factory = (IWICComponentFactory) new WICImagingFactory();
                com.Add(factory);


                Stopwatch conversion = new Stopwatch();
                conversion.Start();

                IWICBitmap b = ConversionUtils.ToWic(factory, i as Bitmap);

                conversion.Stop();

                Stopwatch encoding = new Stopwatch();
                encoding.Start();

                //Prepare output stream
                var outputStream = new MemoryIStream();

                EncodeToStream(factory, b, i.Size, outputStream);
                encoding.Stop();

                Stopwatch streaming = new Stopwatch();
                streaming.Start();
                outputStream.WriteTo(s);
                streaming.Stop();
            } finally {
                //Manually cleanup all the com reference counts, aggressively
                while (com.Count > 0)
                {
                    Marshal.ReleaseComObject(com[com.Count - 1]); //In reverse order, so no item is ever deleted out from under another.
                    com.RemoveAt(com.Count - 1);
                }
            }
        }
Esempio n. 10
0
        public static IWICBitmapSource GetOrientedImageSource(this IWICImagingFactory factory, IWICBitmapSource source, WICBitmapTransformOptions opt)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }
            if (opt == WICBitmapTransformOptions.WICBitmapTransformRotate0)
            {
                return(source);
            }
            IWICBitmap iwicbitmap = null;

            factory.CreateBitmapFromSource(source, WICBitmapCreateCacheOption.WICBitmapCacheOnDemand, out iwicbitmap);
            IWICBitmapFlipRotator iwicbitmapFlipRotator = null;

            factory.CreateBitmapFlipRotator(out iwicbitmapFlipRotator);
            iwicbitmapFlipRotator.Initialize(iwicbitmap, opt);
            IWICBitmapSource result = iwicbitmapFlipRotator;

            GraphicsInteropNativeMethods.SafeReleaseComObject(iwicbitmap);
            return(result);
        }
Esempio n. 11
0
 internal static extern int CreateBitmapFromMemory(IWICComponentFactory factory, uint width, uint height, ref Guid pixelFormatGuid, uint stride, uint cbBufferSize, IntPtr pvPixels, out IWICBitmap ppIBitmap);
Esempio n. 12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WicBitmap"/> class.
 /// </summary>
 /// <param name="wicBitmap">The unmanaged bitmap data object.</param>
 private WicBitmap(IWICBitmap wicBitmap)
 {
     _wicBitmap = wicBitmap;
 }
Esempio n. 13
0
        private unsafe void SaveScreenshot(string path, ContainerFormat format = ContainerFormat.Jpeg)
        {
            var             d3d11GraphicsDevice = ((D3D11GraphicsDevice)_graphicsDevice !);
            ID3D11Texture2D source = Headless ? d3d11GraphicsDevice !.OffscreenTexture : d3d11GraphicsDevice !.BackBufferTexture;

            path = Path.Combine(AppContext.BaseDirectory, path);

            using (ID3D11Texture2D staging = d3d11GraphicsDevice !.CaptureTexture(source))
            {
                staging.DebugName = "STAGING";

                var textureDesc = staging !.Description;

                // Determine source format's WIC equivalent
                Guid pfGuid = default;
                bool sRGB   = false;
                switch (textureDesc.Format)
                {
                case Format.R32G32B32A32_Float:
                    pfGuid = WICPixelFormat.Format128bppRGBAFloat;
                    break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                default:
                    Console.WriteLine($"ERROR: ScreenGrab does not support all DXGI formats ({textureDesc.Format})");
                    return;
                }

                using var wicFactory = new IWICImagingFactory2();
                //using IWICBitmapDecoder decoder = wicFactory.CreateDecoderFromFileName(path);

                //using Stream stream = File.OpenWrite(path);
                //using IWICStream wicStream = wicFactory.CreateStream(stream);
                using IWICStream wicStream      = wicFactory.CreateStream(path, FileAccess.Write);
                using IWICBitmapEncoder encoder = wicFactory.CreateEncoder(format, wicStream);
                // Create a Frame encoder
                using IWICBitmapFrameEncode frame = encoder.CreateNewFrame(out SharpGen.Runtime.Win32.IPropertyBag2? props);
                frame.Initialize(props);
                frame.SetSize(textureDesc.Width, textureDesc.Height);
                frame.SetResolution(72, 72);

                // Screenshots don't typically include the alpha channel of the render target
                Guid targetGuid;
                switch (textureDesc.Format)
                {
                case Format.R32G32B32A32_Float:
                case Format.R16G16B16A16_Float:
                    //if (IsWIC2())
                {
                    targetGuid = WICPixelFormat.Format96bppRGBFloat;
                }
                    //else
                    //{
                    //    targetGuid = WICPixelFormat.Format24bppBGR;
                    //}
                    break;

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

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

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

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

                default:
                    targetGuid = WICPixelFormat.Format24bppBGR;
                    break;
                }
                frame.SetPixelFormat(targetGuid);

                ID3D11DeviceContext1 context = d3d11GraphicsDevice !.DeviceContext;

                const bool native = false;
                if (native)
                {
                    MappedSubresource mappedSubresource = context.Map(staging, 0, MapMode.Read);
                    int imageSize = mappedSubresource.RowPitch * textureDesc.Height;
                    if (targetGuid != pfGuid)
                    {
                        // Conversion required to write
                        using (IWICBitmap bitmapSource = wicFactory.CreateBitmapFromMemory(
                                   textureDesc.Width,
                                   textureDesc.Height,
                                   pfGuid,
                                   mappedSubresource.RowPitch,
                                   imageSize,
                                   mappedSubresource.DataPointer))
                        {
                            using (IWICFormatConverter formatConverter = wicFactory.CreateFormatConverter())
                            {
                                if (!formatConverter.CanConvert(pfGuid, targetGuid))
                                {
                                    context.Unmap(staging, 0);
                                    return;
                                }

                                formatConverter.Initialize(bitmapSource, targetGuid, BitmapDitherType.None, null, 0, BitmapPaletteType.MedianCut);
                                frame.WriteSource(formatConverter, new RectI(textureDesc.Width, textureDesc.Height));
                            }
                        }
                    }
                    else
                    {
                        // No conversion required
                        frame.WritePixels(textureDesc.Height, mappedSubresource.RowPitch, imageSize, mappedSubresource.DataPointer);
                    }
                }
                else
                {
                    int stride = WICPixelFormat.GetStride(pfGuid, textureDesc.Width);
                    ReadOnlySpan <Color> colors = context.MapReadOnly <Color>(staging);

                    if (targetGuid != pfGuid)
                    {
                        // Conversion required to write
                        using (IWICBitmap bitmapSource = wicFactory.CreateBitmapFromMemory(
                                   textureDesc.Width,
                                   textureDesc.Height,
                                   pfGuid,
                                   colors,
                                   stride))
                        {
                            using (IWICFormatConverter formatConverter = wicFactory.CreateFormatConverter())
                            {
                                if (!formatConverter.CanConvert(pfGuid, targetGuid))
                                {
                                    context.Unmap(staging, 0);
                                    return;
                                }

                                formatConverter.Initialize(bitmapSource, targetGuid, BitmapDitherType.None, null, 0, BitmapPaletteType.MedianCut);
                                frame.WriteSource(formatConverter, new RectI(textureDesc.Width, textureDesc.Height));
                            }
                        }
                    }
                    else
                    {
                        // No conversion required
                        frame.WritePixels(textureDesc.Height, stride, colors);
                    }
                }

                context.Unmap(staging, 0);
                frame.Commit();
                encoder.Commit();
            }
        }
Esempio n. 14
0
 internal static extern int CreateBitmapFromMemory(IWICComponentFactory factory, uint width, uint height, ref Guid pixelFormatGuid, uint stride, uint cbBufferSize, IntPtr pvPixels, out IWICBitmap ppIBitmap);
Esempio n. 15
0
 public void Dispose()
 {
     if (m_internalBitmap != null)
     {
         Marshal.ReleaseComObject(m_internalBitmap);
         m_internalBitmap = null;
     }
 }
Esempio n. 16
0
 internal Image(IWICBitmap internalWicBitmap)
 {
     m_internalBitmap = internalWicBitmap;
     Initialize();
 }
Esempio n. 17
0
        public static IComObject <T> CreateWicBitmapRenderTarget <T>(this ID2D1Factory factory, IWICBitmap target, D2D1_RENDER_TARGET_PROPERTIES?renderTargetProperties = null) where T : ID2D1RenderTarget
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            var props = renderTargetProperties ?? new D2D1_RENDER_TARGET_PROPERTIES();

            factory.CreateWicBitmapRenderTarget(target, ref props, out var renderTarget).ThrowOnError();
            return(new ComObject <T>((T)renderTarget));
        }
Esempio n. 18
0
        protected override bool ProcessEncoder(MainForm form, IWICBitmapEncoder encoder, object tag)
        {
            IWICImagingFactory    factory = (IWICImagingFactory) new WICImagingFactory();
            IWICBitmap            bitmap  = factory.CreateBitmap(1, 1, Consts.GUID_WICPixelFormat128bpp7ChannelsAlpha, WICBitmapCreateCacheOption.WICBitmapCacheOnLoad);
            IWICBitmapFrameEncode frame   = null;

            try
            {
                try
                {
                    encoder.CreateNewFrame(out frame, null);
                }
                catch (Exception e)
                {
                    form.Add(this, e.TargetSite.ToString(Resources._0_Failed), new DataEntry(e));
                }

                if (frame != null)
                {
                    try
                    {
                        frame.Initialize(null);
                    }
                    catch (Exception e)
                    {
                        form.Add(this, e.TargetSite.ToString(Resources._0_Failed, "NULL"), new DataEntry(e));
                        frame.ReleaseComObject();
                        frame = null;
                    }
                }
                if (frame != null)
                {
                    try
                    {
                        frame.WriteSource(bitmap, null);
                    }
                    catch (Exception e)
                    {
                        form.Add(this, e.TargetSite.ToString(Resources._0_Failed, "..., NULL"), new DataEntry(e));
                        frame.ReleaseComObject();
                        frame = null;
                    }
                }

                if (frame != null)
                {
                    try
                    {
                        frame.Commit();
                        encoder.Commit();
                    }
                    catch (Exception e)
                    {
                        form.Add(this, e.TargetSite.ToString(Resources._0_Failed), new DataEntry(e));
                    }
                }
            }
            finally
            {
                frame.ReleaseComObject();
                bitmap.ReleaseComObject();
                factory.ReleaseComObject();
            }

            return(base.ProcessEncoder(form, encoder, tag));
        }
Esempio n. 19
0
            private unsafe void SaveScreenshot(string path, ContainerFormat format = ContainerFormat.Jpeg)
            {
                var             d3d11GraphicsDevice = ((D3D11GraphicsDevice)_graphicsDevice !);
                ID3D11Texture2D source = Headless ? d3d11GraphicsDevice !.OffscreenTexture : d3d11GraphicsDevice !.BackBufferTexture;

                using (ID3D11Texture2D staging = d3d11GraphicsDevice !.CaptureTexture(source))
                {
                    staging.DebugName = "STAGING";

                    var textureDesc = staging !.Description;

                    // Determine source format's WIC equivalent
                    Guid pfGuid = default;
                    bool sRGB   = false;
                    switch (textureDesc.Format)
                    {
                    case Vortice.DXGI.Format.R32G32B32A32_Float:
                        pfGuid = WICPixelFormat.Format128bppRGBAFloat;
                        break;

                    //case DXGI_FORMAT_R16G16B16A16_FLOAT: pfGuid = GUID_WICPixelFormat64bppRGBAHalf; break;
                    //case DXGI_FORMAT_R16G16B16A16_UNORM: pfGuid = GUID_WICPixelFormat64bppRGBA; break;
                    //case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: pfGuid = GUID_WICPixelFormat32bppRGBA1010102XR; break; // DXGI 1.1
                    //case DXGI_FORMAT_R10G10B10A2_UNORM: pfGuid = GUID_WICPixelFormat32bppRGBA1010102; break;
                    //case DXGI_FORMAT_B5G5R5A1_UNORM: pfGuid = GUID_WICPixelFormat16bppBGRA5551; break;
                    //case DXGI_FORMAT_B5G6R5_UNORM: pfGuid = GUID_WICPixelFormat16bppBGR565; break;
                    //case DXGI_FORMAT_R32_FLOAT: pfGuid = GUID_WICPixelFormat32bppGrayFloat; break;
                    //case DXGI_FORMAT_R16_FLOAT: pfGuid = GUID_WICPixelFormat16bppGrayHalf; break;
                    //case DXGI_FORMAT_R16_UNORM: pfGuid = GUID_WICPixelFormat16bppGray; break;
                    //case DXGI_FORMAT_R8_UNORM: pfGuid = GUID_WICPixelFormat8bppGray; break;
                    //case DXGI_FORMAT_A8_UNORM: pfGuid = GUID_WICPixelFormat8bppAlpha; break;

                    case Vortice.DXGI.Format.R8G8B8A8_UNorm:
                        pfGuid = WICPixelFormat.Format32bppRGBA;
                        break;

                    case Vortice.DXGI.Format.R8G8B8A8_UNorm_SRgb:
                        pfGuid = WICPixelFormat.Format32bppRGBA;
                        sRGB   = true;
                        break;

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

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

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

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

                    default:
                        //Console.WriteLine("ERROR: ScreenGrab does not support all DXGI formats (%u). Consider using DirectXTex.\n", static_cast<uint32_t>(desc.Format));
                        return;
                    }

                    // Screenshots don't typically include the alpha channel of the render target
                    Guid targetGuid = default;
                    switch (textureDesc.Format)
                    {
                    case Vortice.DXGI.Format.R32G32B32A32_Float:
                    case Vortice.DXGI.Format.R16G16B16A16_Float:
                        //if (_IsWIC2())
                    {
                        targetGuid = WICPixelFormat.Format96bppRGBFloat;
                    }
                        //else
                        //{
                        //    targetGuid = WICPixelFormat.Format24bppBGR;
                        //}
                        break;

                    case Vortice.DXGI.Format.R16G16B16A16_UNorm:
                        targetGuid = WICPixelFormat.Format48bppBGR;
                        break;

                    case Vortice.DXGI.Format.B5G5R5A1_UNorm:
                        targetGuid = WICPixelFormat.Format16bppBGR555;
                        break;

                    case Vortice.DXGI.Format.B5G6R5_UNorm:
                        targetGuid = WICPixelFormat.Format16bppBGR565;
                        break;

                    case Vortice.DXGI.Format.R32_Float:
                    case Vortice.DXGI.Format.R16_Float:
                    case Vortice.DXGI.Format.R16_UNorm:
                    case Vortice.DXGI.Format.R8_UNorm:
                    case Vortice.DXGI.Format.A8_UNorm:
                        targetGuid = WICPixelFormat.Format8bppGray;
                        break;

                    default:
                        targetGuid = WICPixelFormat.Format24bppBGR;
                        break;
                    }

                    using var wicFactory            = new IWICImagingFactory();
                    using IWICBitmapDecoder decoder = wicFactory.CreateDecoderFromFileName(path);


                    using Stream stream             = File.OpenWrite(path);
                    using IWICStream wicStream      = wicFactory.CreateStream(stream);
                    using IWICBitmapEncoder encoder = wicFactory.CreateEncoder(format, wicStream);
                    // Create a Frame encoder
                    var props = new SharpGen.Runtime.Win32.PropertyBag();
                    var frame = encoder.CreateNewFrame(props);
                    frame.Initialize(props);
                    frame.SetSize(textureDesc.Width, textureDesc.Height);
                    frame.SetResolution(72, 72);
                    frame.SetPixelFormat(targetGuid);

                    var context = d3d11GraphicsDevice !.DeviceContext;
                    //var mapped = context.Map(staging, 0, MapMode.Read, MapFlags.None);
                    Span <Color> colors = context.Map <Color>(staging, 0, 0, MapMode.Read, MapFlags.None);

                    // Check conversion
                    if (targetGuid != pfGuid)
                    {
                        // Conversion required to write
                        using (IWICBitmap bitmapSource = wicFactory.CreateBitmapFromMemory(
                                   textureDesc.Width,
                                   textureDesc.Height,
                                   pfGuid,
                                   colors))
                        {
                            using (IWICFormatConverter formatConverter = wicFactory.CreateFormatConverter())
                            {
                                formatConverter.CanConvert(pfGuid, targetGuid, out RawBool canConvert);
                                if (!canConvert)
                                {
                                    context.Unmap(staging, 0);
                                    return;
                                }

                                formatConverter.Initialize(bitmapSource, targetGuid, BitmapDitherType.None, null, 0, BitmapPaletteType.MedianCut);
                                frame.WriteSource(formatConverter, new Rectangle(textureDesc.Width, textureDesc.Height));
                            }
                        }
                    }
                    else
                    {
                        // No conversion required
                        int stride = WICPixelFormat.GetStride(pfGuid, textureDesc.Width);
                        frame.WritePixels(textureDesc.Height, stride, colors);
                    }

                    context.Unmap(staging, 0);
                    frame.Commit();
                    encoder.Commit();
                }
            }
Esempio n. 20
0
 public static void SetResolution(this IWICBitmap bitmap, Resolution resolution)
 {
     bitmap.SetResolution(resolution.DpiX, resolution.DpiY);
 }