public static void WriteSource(this IWICBitmapFrameEncode bitmapFrameEncode, IWICBitmapSource pIBitmapSource, WICRect?prc = null)
 {
     using (var prcPtr = CoTaskMemPtr.From(prc))
     {
         bitmapFrameEncode.WriteSource(pIBitmapSource, prcPtr);
     }
 }
Beispiel #2
0
    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 IWICMetadataQueryWriter GetMetadataQueryWriterNoThrow(this IWICBitmapFrameEncode frame)
        {
            IWICMetadataQueryWriter wri;
            int hr = GetMetadataQueryWriter(frame, out wri);

            return(hr >= 0 ? wri : null);
        }
Beispiel #4
0
        private static unsafe void EncodeImage(PixelBuffer image, WICFlags flags, IWICBitmapFrameEncode 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);
            var targetGuid = pfGuid;

            frame.SetPixelFormat(ref targetGuid);

            if (targetGuid != pfGuid)
            {
                using (var source = Factory.CreateBitmapFromMemory(image.Width, image.Height, pfGuid, image.RowStride, image.BufferStride, image.DataPointer.ToPointer()))
                {
                    using (var converter = Factory.CreateFormatConverter())
                    {
                        using (var palette = Factory.CreatePalette())
                        {
                            palette.InitializeFromBitmap(source, 256, true);
                            converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, BitmapPaletteType.Custom);

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

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

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

            frame.Commit();
        }
Beispiel #5
0
        public static void SetSize(this IWICBitmapFrameEncode frame, uint width, uint height)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.SetSize(width, height).ThrowOnError();
        }
Beispiel #6
0
        public static void SetResolution(this IWICBitmapFrameEncode frame, double dpiX, double dpiY)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.SetResolution(dpiX, dpiY).ThrowOnError();
        }
Beispiel #7
0
        public static void SetPixelFormat(this IWICBitmapFrameEncode frame, Guid pixelFormat)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.SetPixelFormat(pixelFormat).ThrowOnError();
        }
Beispiel #8
0
        public static void SetThumbnail(this IWICBitmapFrameEncode frame, IWICBitmapSource thumbnail)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.SetThumbnail(thumbnail).ThrowOnError();
        }
Beispiel #9
0
        public static void SetPalette(this IWICBitmapFrameEncode frame, IWICPalette palette)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.SetPalette(palette).ThrowOnError();
        }
Beispiel #10
0
        public static void SetColorContexts(this IWICBitmapFrameEncode frame, IEnumerable <IWICColorContext> contexts)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.SetColorContexts((contexts?.Count()).GetValueOrDefault(), contexts?.ToArray()).ThrowOnError();
        }
Beispiel #11
0
        public static void Commit(this IWICBitmapFrameEncode frame)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.Commit().ThrowOnError();
        }
Beispiel #12
0
        public static IComObject <IWICMetadataQueryWriter> GetMetadataQueryWriter(this IWICBitmapFrameEncode frame)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            frame.GetMetadataQueryWriter(out var writer).ThrowOnError();
            return(new ComObject <IWICMetadataQueryWriter>(writer));
        }
Beispiel #13
0
        public WicEncoder(WicProcessingContext ctx, IStream stm)
        {
            Encoder = ctx.AddRef(Wic.Factory.CreateEncoder(formatMap.GetValueOrDefault(ctx.Settings.SaveFormat, () => Consts.GUID_ContainerFormatPng), null));
            Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

            var props = new Dictionary <string, object>();
            var bag   = default(IPropertyBag2);

            Encoder.CreateNewFrame(out var frame, ref bag);
            ctx.AddRef(frame);
            ctx.AddRef(bag);

            if (ctx.Settings.SaveFormat == FileFormat.Jpeg)
            {
                props.Add("ImageQuality", ctx.Settings.JpegQuality / 100f);
            }

            if (ctx.Settings.SaveFormat == FileFormat.Jpeg && ctx.Settings.JpegSubsampleMode != ChromaSubsampleMode.Default)
            {
                props.Add("JpegYCrCbSubsampling", (byte)ctx.Settings.JpegSubsampleMode);
            }

            if (ctx.Settings.SaveFormat == FileFormat.Tiff)
            {
                props.Add("TiffCompressionMethod", (byte)WICTiffCompressionOption.WICTiffCompressionNone);
            }

            if (ctx.Settings.SaveFormat == FileFormat.Bmp && ctx.Source.Format.AlphaRepresentation != PixelAlphaRepresentation.None)
            {
                props.Add("EnableV5Header32bppBGRA", true);
            }

            if (props.Count > 0)
            {
                bag.Write((uint)props.Count, props.Keys.Select(k => new PROPBAG2 {
                    pstrName = k
                }).ToArray(), props.Values.ToArray());
            }

            frame.Initialize(bag);
            frame.SetSize(ctx.Source.Width, ctx.Source.Height);
            frame.SetResolution(ctx.Settings.DpiX > 0d ? ctx.Settings.DpiX : ctx.DecoderFrame.DpiX, ctx.Settings.DpiY > 0d ? ctx.Settings.DpiY : ctx.DecoderFrame.DpiY);

            if (ctx.DecoderFrame.Metadata?.Count > 0 && frame.TryGetMetadataQueryWriter(out var metawriter))
            {
                ctx.AddRef(metawriter);
                foreach (var nv in ctx.DecoderFrame.Metadata)
                {
                    metawriter.TrySetMetadataByName(nv.Key, nv.Value);
                }
            }

            Frame = frame;
        }
Beispiel #14
0
        public static void Initialize(this IWICBitmapFrameEncode frame, IPropertyBag2 bag = null)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            if (bag != null)
            {
                frame.Initialize(bag).ThrowOnError();
            }
        }
Beispiel #15
0
        public static void WritePixels(this IWICBitmapFrameEncode frame, uint lineCount, uint stride, byte[] pixels)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

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

            frame.WritePixels(lineCount, stride, pixels.Length, pixels).ThrowOnError();
        }
Beispiel #16
0
        public static void WriteSource(this IWICBitmapFrameEncode frame, IWICBitmapSource source, WICRect?sourceRectangle = null)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

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

            using (var mem = new ComMemory(sourceRectangle))
            {
                frame.WriteSource(source, mem.Pointer).ThrowOnError();
            }
        }
Beispiel #17
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();
                }
            }
        }
 private extern static int GetMetadataQueryWriter(IWICBitmapFrameEncode THIS_PTR, out IWICMetadataQueryWriter ppIMetadataQueryWriter);
 public Result WriteFrame(ID2D1Image image, IWICBitmapFrameEncode frameEncode, WICImageParameters imageParameters)
 {
     return(WriteFrame(image, frameEncode, ref imageParameters));
 }
        protected override bool ProcessEncoder(MainForm form, IWICBitmapEncoder encoder, object tag)
        {
            Tag t = (Tag)tag;
            IWICImagingFactory factory = (IWICImagingFactory) new WICImagingFactory();
            IWICPalette        palette = factory.CreatePalette();

            palette.InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedBW, false);
            IWICBitmapFrameEncode frame  = null;
            IWICBitmapFrameEncode frame2 = null;

            IPropertyBag2[] bag = new IPropertyBag2[1];
            try
            {
                MethodInfo mi = typeof(IWICBitmapEncoder).GetMethod("CreateNewFrame");
                try
                {
                    encoder.CreateNewFrame(out frame, bag);
                }
                catch (Exception e)
                {
                    form.Add(this, mi.ToString(Resources._0_Failed), new DataEntry(Resources.FrameIndex, 0), new DataEntry(e));
                }

                if (frame == null)
                {
                    form.Add(this, mi.ToString(Resources._0_NULL), new DataEntry(Resources.Parameter, mi.GetParameters()[0].Name));
                }
                else
                {
                    if (bag[0] == null)
                    {
                        form.Add(this, mi.ToString(Resources._0_NULL), new DataEntry(Resources.Parameter, mi.GetParameters()[1].Name));
                    }
                    try
                    {
                        frame.Initialize(bag[0]);
                        frame.SetSize(1, 1);
                        frame.SetPalette(palette);
                        Guid pixelFormat = Guid.Empty;

                        List <Guid> allPixelFormats = new List <Guid>(PixelFormatInfoRule.AllPixelFormats);
                        allPixelFormats.Add(Consts.GUID_WICPixelFormatDontCare);

                        foreach (Guid g in allPixelFormats)
                        {
                            pixelFormat = g;
                            frame.SetPixelFormat(ref pixelFormat);
                            if (g == pixelFormat)
                            {
                                if (Array.IndexOf(t.PixelFormats, g) < 0)
                                {
                                    form.Add(this, string.Format(CultureInfo.CurrentUICulture, Resources.DidNotChangeUnsupportedPixelFormat, "IWICBitmapFrameEncode::SetPixelFormat(...)"), new DataEntry(Resources.PixelFormat, g), new DataEntry(Resources.SupportedPixelFormats, t.PixelFormats));
                                }
                            }
                            else
                            {
                                if (Array.IndexOf(t.PixelFormats, g) >= 0)
                                {
                                    form.Add(this, string.Format(CultureInfo.CurrentUICulture, Resources.ChangedSupportedPixelFormat, "IWICBitmapFrameEncode::SetPixelFormat(...)"), new DataEntry(Resources.Expected, g), new DataEntry(Resources.Actual, pixelFormat));
                                }
                            }
                        }
                        pixelFormat = Consts.GUID_WICPixelFormat32bppBGRA;
                        frame.SetPixelFormat(ref pixelFormat);
                        byte[] buffer = new byte[(PixelFormatInfoRule.GetBitPerPixel(pixelFormat) + 7) / 8];
                        frame.WritePixels(1, (uint)buffer.Length, (uint)buffer.Length, buffer);
                        frame.Commit();

                        try
                        {
                            encoder.CreateNewFrame(out frame2, null);
                            if (!t.SupportsMultiframe)
                            {
                                form.Add(this, mi.ToString(Resources._0_ShouldFail), new DataEntry(WinCodecError.WINCODEC_ERR_UNSUPPORTEDOPERATION));
                            }
                        }
                        catch (Exception e)
                        {
                            if (t.SupportsMultiframe)
                            {
                                form.Add(this, e.TargetSite.ToString(Resources._0_Failed), new DataEntry(Resources.FrameIndex, 1), new DataEntry(e));
                            }
                            else
                            {
                                form.CheckHRESULT(this, WinCodecError.WINCODEC_ERR_UNSUPPORTEDOPERATION, e, new DataEntry(Resources.FrameIndex, 1));
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        form.Add(this, e.TargetSite.ToString(Resources._0_Failed), new DataEntry(e));
                    }
                }
            }
            finally
            {
                frame2.ReleaseComObject();
                encoder.ReleaseComObject();
                bag.ReleaseComObject();
                factory.ReleaseComObject();
                palette.ReleaseComObject();
            }

            return(base.ProcessEncoder(form, encoder, tag));
        }
Beispiel #21
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();
            }
        }
Beispiel #22
0
        public WicEncoder(IStream stm, WicProcessingContext ctx)
        {
            var frame = (IWICBitmapFrameEncode)null;

            if (ctx.Settings.SaveFormat == FileFormat.Jpeg)
            {
                Encoder = AddRef(Wic.CreateEncoder(Consts.GUID_ContainerFormatJpeg, null));
                Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                var bag = (IPropertyBag2)null;
                Encoder.CreateNewFrame(out frame, ref bag);
                AddRef(frame);
                AddRef(bag);

                if (ctx.Settings.JpegSubsampleMode != ChromaSubsampleMode.Default)
                {
                    var props = new PROPBAG2[] { new PROPBAG2 {
                                                     pstrName = "ImageQuality"
                                                 }, new PROPBAG2 {
                                                     pstrName = "JpegYCrCbSubsampling"
                                                 } };
                    bag.Write(2, props, new object[] { ctx.Settings.JpegQuality / 100f, (byte)ctx.Settings.JpegSubsampleMode });
                }
                else
                {
                    var props = new PROPBAG2[] { new PROPBAG2 {
                                                     pstrName = "ImageQuality"
                                                 } };
                    bag.Write(1, props, new object[] { ctx.Settings.JpegQuality / 100f });
                }

                frame.Initialize(bag);
            }
            else if (ctx.Settings.SaveFormat == FileFormat.Gif)
            {
                Encoder = AddRef(Wic.CreateEncoder(Consts.GUID_ContainerFormatGif, null));
                Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);
                Encoder.SetPalette(ctx.DestPalette);

                Encoder.CreateNewFrame(out frame, null);
                AddRef(frame);

                frame.Initialize(null);
            }
            else if (ctx.Settings.SaveFormat == FileFormat.Bmp)
            {
                Encoder = AddRef(Wic.CreateEncoder(Consts.GUID_ContainerFormatBmp, null));
                Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                var bag = (IPropertyBag2)null;
                Encoder.CreateNewFrame(out frame, ref bag);
                AddRef(frame);
                AddRef(bag);

                var props = new PROPBAG2[] { new PROPBAG2 {
                                                 pstrName = "EnableV5Header32bppBGRA"
                                             } };
                bag.Write(1, props, new object[] { ctx.PixelFormat == Consts.GUID_WICPixelFormat32bppBGRA });

                frame.Initialize(bag);
            }
            else if (ctx.Settings.SaveFormat == FileFormat.Tiff)
            {
                Encoder = AddRef(Wic.CreateEncoder(Consts.GUID_ContainerFormatTiff, null));
                Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                var bag = (IPropertyBag2)null;
                Encoder.CreateNewFrame(out frame, ref bag);
                AddRef(frame);
                AddRef(bag);

                var props = new PROPBAG2[] { new PROPBAG2 {
                                                 pstrName = "TiffCompressionMethod"
                                             } };
                bag.Write(1, props, new object[] { (byte)WICTiffCompressionOption.WICTiffCompressionNone });

                frame.Initialize(bag);
            }
            else
            {
                Encoder = AddRef(Wic.CreateEncoder(Consts.GUID_ContainerFormatPng, null));
                Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                Encoder.CreateNewFrame(out frame, null);
                AddRef(frame);

                frame.Initialize(null);
            }

            frame.SetResolution(96d, 96d);
            frame.SetSize(ctx.Width, ctx.Height);

            if (ctx.Settings.IndexedColor && ctx.PixelFormat == Consts.GUID_WICPixelFormat8bppIndexed)
            {
                frame.SetPalette(ctx.DestPalette);
            }

            if (ctx.Metadata?.Count > 0)
            {
                var metawriter = frame.GetMetadataQueryWriterNoThrow();
                if (metawriter != null)
                {
                    AddRef(metawriter);
                    foreach (var nv in ctx.Metadata)
                    {
                        metawriter.SetMetadataByNameNoThrow(nv.Key, nv.Value);
                    }
                }
            }

            // TODO setting
            //if (ctx.DestColorContext != null)
            //	frame.SetColorContexts(1, new IWICColorContext[] { ctx.DestColorContext });

            Frame = frame;
        }
 public static IWICMetadataBlockWriter AsMetadataBlockWriter(this IWICBitmapFrameEncode bitmapFrameEncode)
 {
     return(bitmapFrameEncode as IWICMetadataBlockWriter);
 }
 public static void WritePixels(this IWICBitmapFrameEncode bitmapFrameEncode, int lineCount, int cbStride, byte[] pbPixels)
 {
     bitmapFrameEncode.WritePixels(lineCount, cbStride, pbPixels.Length, pbPixels);
 }
        public static bool TrySetColorContexts(this IWICBitmapFrameEncode frame, params IWICColorContext[] contexts)
        {
            int hr = ProxyFunctions.SetColorContexts(frame, (uint)contexts.Length, contexts);

            return(hr >= 0);
        }
Beispiel #26
0
        public WicEncoder(PipelineContext ctx, IStream stm)
        {
            var fmt = ctx.Settings.SaveFormat;

            Encoder = ctx.WicContext.AddRef(Wic.Factory.CreateEncoder(formatMap.GetValueOrDefault(fmt, Consts.GUID_ContainerFormatPng), null));
            Encoder.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

            var bag = default(IPropertyBag2);

            Encoder.CreateNewFrame(out var frame, ref bag);
            ctx.WicContext.AddRef(frame);
            ctx.WicContext.AddRef(bag);

            if (fmt == FileFormat.Jpeg)
            {
                bag.Write("ImageQuality", ctx.Settings.JpegQuality / 100f);
            }

            if (fmt == FileFormat.Jpeg && ctx.Settings.JpegSubsampleMode != ChromaSubsampleMode.Default)
            {
                bag.Write("JpegYCrCbSubsampling", (byte)ctx.Settings.JpegSubsampleMode);
            }

            if (fmt == FileFormat.Tiff)
            {
                bag.Write("TiffCompressionMethod", (byte)WICTiffCompressionOption.WICTiffCompressionNone);
            }

            if (fmt == FileFormat.Bmp && ctx.Source.Format.AlphaRepresentation != PixelAlphaRepresentation.None)
            {
                bag.Write("EnableV5Header32bppBGRA", true);
            }

            frame.Initialize(bag);
            frame.SetSize((uint)ctx.Source.Width, (uint)ctx.Source.Height);
            frame.SetResolution(ctx.Settings.DpiX > 0d ? ctx.Settings.DpiX : ctx.ImageFrame.DpiX, ctx.Settings.DpiY > 0d ? ctx.Settings.DpiY : ctx.ImageFrame.DpiY);

            if (frame.TryGetMetadataQueryWriter(out var metawriter))
            {
                ctx.WicContext.AddRef(metawriter);
                if (ctx.ImageFrame is WicImageFrame wicFrame && wicFrame.WicMetadataReader != null && ctx.Settings.MetadataNames != Enumerable.Empty <string>())
                {
                    foreach (string prop in ctx.Settings.MetadataNames)
                    {
                        if (wicFrame.WicMetadataReader.TryGetMetadataByName(prop, out var pvar) && !(pvar.Value is null))
                        {
                            metawriter.TrySetMetadataByName(prop, pvar);
                        }
                    }
                }

                if (ctx.Settings.OrientationMode == OrientationMode.Preserve && ctx.ImageFrame.ExifOrientation != Orientation.Normal)
                {
                    string orientationPath = ctx.Settings.SaveFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpegPath : Wic.Metadata.OrientationExifPath;
                    metawriter.TrySetMetadataByName(orientationPath, new PropVariant((ushort)ctx.ImageFrame.ExifOrientation));
                }
            }

            if (ctx.WicContext.DestColorContext != null && (ctx.Settings.ColorProfileMode == ColorProfileMode.NormalizeAndEmbed || ctx.Settings.ColorProfileMode == ColorProfileMode.Preserve))
            {
                var cc = ctx.WicContext.DestColorContext;
                if (ctx.DestColorProfile == ColorProfile.sRGB)
                {
                    cc = WicColorProfile.SrgbCompact.Value.WicColorContext;
                }
                else if (ctx.DestColorProfile == ColorProfile.sGrey)
                {
                    cc = WicColorProfile.GreyCompact.Value.WicColorContext;
                }

                frame.TrySetColorContexts(cc);
            }

            Frame = frame;
        }
        public static bool TryGetMetadataQueryWriter(this IWICBitmapFrameEncode frame, [NotNullWhen(true)] out IWICMetadataQueryWriter?wri)
        {
            int hr = ProxyFunctions.GetMetadataQueryWriter(frame, out wri);

            return(hr >= 0);
        }
 public static void SetResolution(this IWICBitmapFrameEncode bitmapFrameEncode, Resolution resolution)
 {
     bitmapFrameEncode.SetResolution(resolution.DpiX, resolution.DpiY);
 }
        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));
        }
 public static void SetSize(this IWICBitmapFrameEncode bitmapFrameEncode, Size size)
 {
     bitmapFrameEncode.SetSize(size.Width, size.Height);
 }