private static void Save(IWICBitmapSource source, Stream stream, Guid containerFormat, Guid pixelFormat, WICBitmapEncoderCacheOption cacheOptions, WICRect rect) { var wfac = (IWICImagingFactory) new WICImagingFactory(); IWICBitmapEncoder encoder = null; IWICBitmapFrameEncode frame = null; try { encoder = wfac.CreateEncoder(containerFormat, null); encoder.Initialize(new ManagedIStream(stream), cacheOptions); encoder.CreateNewFrame(out frame, IntPtr.Zero); frame.Initialize(IntPtr.Zero); if (pixelFormat != Guid.Empty) { frame.SetPixelFormat(pixelFormat); } frame.WriteSource(source, rect); frame.Commit(); encoder.Commit(); } finally { Release(frame); Release(encoder); Release(wfac); } }
public static void Save(this IWICImagingFactory factory, IWICBitmapSource imageSource, IWICStream stream, Guid encoderId) { if (factory == null) { throw new ArgumentNullException("factory"); } if (imageSource == null) { throw new ArgumentNullException("imageSource"); } if (stream == null) { throw new ArgumentNullException("stream"); } IWICBitmapEncoder iwicbitmapEncoder = factory.CreateEncoder(ref encoderId, null); iwicbitmapEncoder.Initialize(stream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache); IWICBitmapFrameEncode iwicbitmapFrameEncode; iwicbitmapEncoder.CreateNewFrame(out iwicbitmapFrameEncode, null); iwicbitmapFrameEncode.Initialize(null); iwicbitmapFrameEncode.WriteSource(imageSource, null); iwicbitmapFrameEncode.Commit(); iwicbitmapEncoder.Commit(); GraphicsInteropNativeMethods.SafeReleaseComObject(iwicbitmapEncoder); GraphicsInteropNativeMethods.SafeReleaseComObject(iwicbitmapFrameEncode); }
public static void Commit(this IWICBitmapEncoder encoder) { if (encoder == null) { throw new ArgumentNullException(nameof(encoder)); } encoder.Commit().ThrowOnError(); }
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(); } } }
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)); }
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(); } }
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)); }
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(); } }
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); }