예제 #1
0
        public virtual void Dispose()
        {
            if (WicEncoderFrame is null)
            {
                return;
            }

            WicEncoderFrame->Release();
            WicEncoderFrame = null;
        }
예제 #2
0
        public WicImageEncoderFrame(PipelineContext ctx, WicImageEncoder encoder, PixelArea area = default)
        {
            var fmt       = ctx.Settings.SaveFormat;
            var encArea   = area.IsEmpty ? ctx.Source.Area : area;
            var colorMode = ctx.Settings.ColorProfileMode;

            using var frame = default(ComPtr <IWICBitmapFrameEncode>);
            using (var pbag = default(ComPtr <IPropertyBag2>))
            {
                HRESULT.Check(encoder.WicEncoder->CreateNewFrame(frame.GetAddressOf(), pbag.GetAddressOf()));

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

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

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

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

                HRESULT.Check(frame.Get()->Initialize(pbag));
            }

            HRESULT.Check(frame.Get()->SetSize((uint)encArea.Width, (uint)encArea.Height));
            HRESULT.Check(frame.Get()->SetResolution(ctx.Settings.DpiX > 0d ? ctx.Settings.DpiX : ctx.ImageFrame.DpiX, ctx.Settings.DpiY > 0d ? ctx.Settings.DpiY : ctx.ImageFrame.DpiY));

            bool copySourceMetadata = ctx.ImageFrame is WicImageFrame srcFrame && srcFrame.WicMetadataReader is not null && ctx.Settings.MetadataNames != Enumerable.Empty <string>();
            bool writeOrientation   = ctx.Settings.OrientationMode == OrientationMode.Preserve && ctx.ImageFrame.ExifOrientation != Orientation.Normal;
            bool writeColorContext  = colorMode == ColorProfileMode.NormalizeAndEmbed || colorMode == ColorProfileMode.Preserve || (colorMode == ColorProfileMode.Normalize && ctx.DestColorProfile != ColorProfile.sRGB && ctx.DestColorProfile != ColorProfile.sGrey);

            using var metawriter = default(ComPtr <IWICMetadataQueryWriter>);
            if ((copySourceMetadata || writeOrientation) && SUCCEEDED(frame.Get()->GetMetadataQueryWriter(metawriter.GetAddressOf())))
            {
                if (copySourceMetadata)
                {
                    var wicFrame = (WicImageFrame)ctx.ImageFrame;
                    foreach (string prop in ctx.Settings.MetadataNames)
                    {
                        var pv = default(PROPVARIANT);
                        if (SUCCEEDED(wicFrame.WicMetadataReader->GetMetadataByName(prop, &pv)) && pv.vt != (ushort)VARENUM.VT_EMPTY)
                        {
                            _ = metawriter.Get()->SetMetadataByName(prop, &pv);
                        }
                    }
                }

                if (writeOrientation)
                {
                    string orientationPath = ctx.Settings.SaveFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpeg : Wic.Metadata.OrientationExif;
                    var    pv = new PROPVARIANT {
                        vt = (ushort)VARENUM.VT_UI2
                    };
                    pv.Anonymous.uiVal = (ushort)ctx.ImageFrame.ExifOrientation;
                    _ = metawriter.Get()->SetMetadataByName(orientationPath, &pv);
                }
            }

            if (writeColorContext)
            {
                Debug.Assert(ctx.WicContext.DestColorContext is not null || ctx.DestColorProfile is not null);

                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;
                }
                else if (ctx.DestColorProfile == ColorProfile.AdobeRgb)
                {
                    cc = WicColorProfile.AdobeRgb.Value.WicColorContext;
                }
                else if (ctx.DestColorProfile == ColorProfile.DisplayP3)
                {
                    cc = WicColorProfile.DisplayP3Compact.Value.WicColorContext;
                }

                using var ccc = default(ComPtr <IWICColorContext>);
                if (cc is null)
                {
                    ccc.Attach(WicColorProfile.CreateContextFromProfile(ctx.DestColorProfile !.ProfileBytes));
                    cc = ccc;
                }

                _ = frame.Get()->SetColorContexts(1, &cc);
            }

            WicEncoderFrame = frame.Detach();
        }
 public int WriteFrameThumbnail(ID2D1Image *pImage, IWICBitmapFrameEncode *pFrameEncode, [NativeTypeName("const WICImageParameters *")] WICImageParameters *pImageParameters)
 {
     return(((delegate * unmanaged <IWICImageEncoder *, ID2D1Image *, IWICBitmapFrameEncode *, WICImageParameters *, int>)(lpVtbl[4]))((IWICImageEncoder *)Unsafe.AsPointer(ref this), pImage, pFrameEncode, pImageParameters));
 }