Beispiel #1
0
 public WicImageEncoder(FileFormat format, IStream stm)
 {
     encoder = ComHandle.Wrap(Wic.Factory.CreateEncoder(formatMap.GetValueOrDefault(format, Consts.GUID_ContainerFormatPng), null));
     encoder.ComObject.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);
 }
Beispiel #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;

            var bag = default(IPropertyBag2);

            encoder.WicEncoder.CreateNewFrame(out var frame, ref bag);
            encoderFrame = ComHandle.Wrap(frame);

            using (var cbag = ComHandle.Wrap(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)encArea.Width, (uint)encArea.Height);
            frame.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);

            if ((copySourceMetadata || writeOrientation) && frame.TryGetMetadataQueryWriter(out var metawriter))
            {
                using var cmeta = ComHandle.Wrap(metawriter);
                if (copySourceMetadata)
                {
                    var wicFrame = (WicImageFrame)ctx.ImageFrame;
                    foreach (string prop in ctx.Settings.MetadataNames)
                    {
                        if (wicFrame.WicMetadataReader !.TryGetMetadataByName(prop, out var pvar) && pvar.Value is not null)
                        {
                            metawriter.TrySetMetadataByName(prop, pvar);
                        }
                    }
                }

                if (writeOrientation)
                {
                    string orientationPath = ctx.Settings.SaveFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpeg : Wic.Metadata.OrientationExif;
                    metawriter.TrySetMetadataByName(orientationPath, new PropVariant((ushort)ctx.ImageFrame.ExifOrientation));
                }
            }

            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;
                }

                frame.TrySetColorContexts(cc ?? ctx.WicContext.AddRef(WicColorProfile.CreateContextFromProfile(ctx.DestColorProfile !.ProfileBytes)));
            }
        }