public WicDecoder(Stream inFile, WicProcessingContext ctx) { var stm = AddRef(Wic.CreateStream()); stm.InitializeFromIStream(inFile.AsIStream()); init(checkDecoder(() => Wic.CreateDecoderFromStream(stm, null, WICDecodeOptions.WICDecodeMetadataCacheOnDemand)), ctx); }
public static void AddHighQualityScaler(WicProcessingContext ctx) { uint width = (uint)ctx.Settings.Width, height = (uint)ctx.Settings.Height; var fmt = ctx.Source.Format; var interpolator = ctx.Settings.Interpolation.WeightingFunction.Support > 1d && fmt.ColorRepresentation == PixelColorRepresentation.Unspecified ? InterpolationSettings.Hermite : ctx.Settings.Interpolation; var interpolatorx = width == ctx.Source.Width ? InterpolationSettings.NearestNeighbor : interpolator; var interpolatory = height == ctx.Source.Height ? InterpolationSettings.NearestNeighbor : interpolator; if (fmt.NumericRepresentation == PixelNumericRepresentation.Float) { var mx = ctx.AddDispose(KernelMap <float> .MakeScaleMap(ctx.Source.Width, width, fmt.ColorChannelCount, fmt.AlphaRepresentation != PixelAlphaRepresentation.None, true, interpolatorx)); var my = ctx.AddDispose(KernelMap <float> .MakeScaleMap(ctx.Source.Height, height, fmt.ChannelCount == 3 ? 4 : fmt.ColorChannelCount, fmt.AlphaRepresentation != PixelAlphaRepresentation.None, true, interpolatory)); ctx.Source = ctx.AddDispose(new ConvolutionTransform <float, float>(ctx.Source, mx, my)); } else { var mx = ctx.AddDispose(KernelMap <int> .MakeScaleMap(ctx.Source.Width, width, 1, fmt.AlphaRepresentation == PixelAlphaRepresentation.Unassociated, false, interpolatorx)); var my = ctx.AddDispose(KernelMap <int> .MakeScaleMap(ctx.Source.Height, height, 1, fmt.AlphaRepresentation == PixelAlphaRepresentation.Unassociated, false, interpolatory)); if (fmt.NumericRepresentation == PixelNumericRepresentation.Fixed) { ctx.Source = ctx.AddDispose(new ConvolutionTransform <ushort, int>(ctx.Source, mx, my)); } else { ctx.Source = ctx.AddDispose(new ConvolutionTransform <byte, int>(ctx.Source, mx, my)); } } }
public static void AddExternalFormatConverter(WicProcessingContext ctx) { var ifmt = ctx.Source.Format.FormatGuid; var ofmt = ifmt; if (ifmt == PixelFormat.Grey32BppFloat.FormatGuid || ifmt == PixelFormat.Grey32BppLinearFloat.FormatGuid || ifmt == PixelFormat.Grey16BppLinearUQ15.FormatGuid) { ofmt = Consts.GUID_WICPixelFormat8bppGray; } else if (ifmt == PixelFormat.Y32BppFloat.FormatGuid || ifmt == PixelFormat.Y32BppLinearFloat.FormatGuid || ifmt == PixelFormat.Y16BppLinearUQ15.FormatGuid) { ofmt = Consts.GUID_WICPixelFormat8bppY; } else if (ifmt == PixelFormat.Bgrx128BppFloat.FormatGuid || ifmt == PixelFormat.Bgrx128BppLinearFloat.FormatGuid || ifmt == PixelFormat.Bgr96BppFloat.FormatGuid || ifmt == PixelFormat.Bgr96BppLinearFloat.FormatGuid || ifmt == PixelFormat.Bgr48BppLinearUQ15.FormatGuid) { ofmt = Consts.GUID_WICPixelFormat24bppBGR; } else if (ifmt == PixelFormat.Pbgra128BppFloat.FormatGuid || ifmt == PixelFormat.Bgra128BppLinearFloat.FormatGuid || ifmt == PixelFormat.Pbgra128BppLinearFloat.FormatGuid || ifmt == PixelFormat.Bgra64BppLinearUQ15.FormatGuid || ifmt == PixelFormat.Pbgra64BppLinearUQ15.FormatGuid) { ofmt = Consts.GUID_WICPixelFormat32bppBGRA; } else if (ifmt == PixelFormat.CbCr64BppFloat.FormatGuid) { ofmt = Consts.GUID_WICPixelFormat16bppCbCr; } if (ofmt == ifmt) { return; } bool forceSrgb = (ifmt == PixelFormat.Y32BppLinearFloat.FormatGuid || ifmt == PixelFormat.Y16BppLinearUQ15.FormatGuid) && ctx.SourceColorProfile != ColorProfile.sRGB; ctx.Source = ctx.AddDispose(new FormatConversionTransform(ctx.Source, forceSrgb ? ColorProfile.sRGB : ctx.SourceColorProfile, forceSrgb ? ColorProfile.sRGB : ctx.DestColorProfile, ofmt)); }
public WicDecoder(IPixelSource imgSource, WicProcessingContext ctx) { init(null, ctx); ContainerFormat = FileFormat.Unknown; FrameCount = 1; ctx.Source = imgSource.AsPixelSource(); }
public static void AddUnsharpMask(WicProcessingContext ctx) { var ss = ctx.Settings.UnsharpMask; if (!ctx.Settings.Sharpen || ss.Radius <= 0d || ss.Amount <= 0) { return; } var fmt = ctx.Source.Format; if (fmt.NumericRepresentation == PixelNumericRepresentation.Float) { var mapx = ctx.AddDispose(KernelMap <float> .MakeBlurMap(ctx.Source.Width, ss.Radius, 1, false, true)); var mapy = ctx.AddDispose(KernelMap <float> .MakeBlurMap(ctx.Source.Height, ss.Radius, 1, false, true)); ctx.Source = ctx.AddDispose(new UnsharpMaskTransform <float, float>(ctx.Source, mapx, mapy, ss)); } else { var mapx = ctx.AddDispose(KernelMap <int> .MakeBlurMap(ctx.Source.Width, ss.Radius, 1, false, false)); var mapy = ctx.AddDispose(KernelMap <int> .MakeBlurMap(ctx.Source.Height, ss.Radius, 1, false, false)); if (fmt.NumericRepresentation == PixelNumericRepresentation.Fixed) { ctx.Source = ctx.AddDispose(new UnsharpMaskTransform <ushort, int>(ctx.Source, mapx, mapy, ss)); } else { ctx.Source = ctx.AddDispose(new UnsharpMaskTransform <byte, int>(ctx.Source, mapx, mapy, ss)); } } }
public static void AddPlanarCache(WicProcessingContext ctx) { if (!(ctx.Source.WicSource is IWICPlanarBitmapSourceTransform trans)) { throw new NotSupportedException("Transform chain doesn't support planar mode. Only JPEG Decoder, Rotator, Scaler, and PixelFormatConverter are allowed"); } double rat = ctx.Settings.HybridScaleRatio.Clamp(1d, 8d); uint width = (uint)Math.Ceiling(ctx.Source.Width / rat); uint height = (uint)Math.Ceiling(ctx.Source.Height / rat); var fmts = new[] { Consts.GUID_WICPixelFormat8bppY, Consts.GUID_WICPixelFormat16bppCbCr }; var desc = new WICBitmapPlaneDescription[2]; var opt = ctx.DecoderFrame.ExifOrientation.ToWicTransformOptions(); if (!trans.DoesSupportTransform(ref width, ref height, opt, WICPlanarOptions.WICPlanarOptionsDefault, fmts, desc, 2)) { throw new NotSupportedException("Requested planar transform not supported"); } var cacheSource = ctx.AddDispose(new WicPlanarCache(trans, desc[0], desc[1], ctx.Settings.Crop.ToWicRect(), opt, width, height, rat)); ctx.PlanarChromaSource = cacheSource.GetPlane(WicPlane.Chroma); ctx.PlanarLumaSource = cacheSource.GetPlane(WicPlane.Luma); ctx.Source = ctx.PlanarChromaSource; ctx.Source = ctx.PlanarLumaSource; }
public WicDecoder(ArraySegment <byte> inBuffer, WicProcessingContext ctx) { var stm = ctx.AddRef(Wic.Factory.CreateStream()); stm.InitializeFromMemory(inBuffer.Array, (uint)inBuffer.Count); init(checkDecoder(() => Wic.Factory.CreateDecoderFromStream(stm, null, WICDecodeOptions.WICDecodeMetadataCacheOnDemand)), ctx); }
public static void AddIndexedColorConverter(WicProcessingContext ctx) { var newFormat = Consts.GUID_WICPixelFormat8bppIndexed; if (!ctx.Settings.IndexedColor || ctx.Source.Format.NumericRepresentation == PixelNumericRepresentation.Indexed || ctx.Source.Format.ColorRepresentation == PixelColorRepresentation.Grey) { return; } var conv = ctx.AddRef(Wic.Factory.CreateFormatConverter()); if (!conv.CanConvert(ctx.Source.Format.FormatGuid, newFormat)) { throw new NotSupportedException("Can't convert to destination pixel format"); } var bmp = ctx.AddRef(Wic.Factory.CreateBitmapFromSource(ctx.Source.WicSource, WICBitmapCreateCacheOption.WICBitmapCacheOnDemand)); ctx.Source = bmp.AsPixelSource(nameof(IWICBitmap)); var pal = ctx.AddRef(Wic.Factory.CreatePalette()); pal.InitializeFromBitmap(ctx.Source.WicSource, 256u, ctx.Source.Format.AlphaRepresentation != PixelAlphaRepresentation.None); ctx.DestPalette = pal; conv.Initialize(ctx.Source.WicSource, newFormat, WICBitmapDitherType.WICBitmapDitherTypeErrorDiffusion, pal, 10.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom); ctx.Source = conv.AsPixelSource(nameof(IWICFormatConverter), false); }
public static void AddScaler(WicProcessingContext ctx, bool hybrid = false) { double rat = ctx.Settings.HybridScaleRatio; if ((ctx.Settings.Width == ctx.Source.Width && ctx.Settings.Height == ctx.Source.Height) || (hybrid && rat == 1d)) { return; } if (ctx.Source.WicSource is IWICBitmapSourceTransform) { ctx.Source = ctx.Source.WicSource.AsPixelSource(nameof(IWICBitmapFrameDecode)); } uint ow = hybrid ? (uint)Math.Ceiling(ctx.Source.Width / rat) : (uint)ctx.Settings.Width; uint oh = hybrid ? (uint)Math.Ceiling(ctx.Source.Height / rat) : (uint)ctx.Settings.Height; var mode = hybrid ? WICBitmapInterpolationMode.WICBitmapInterpolationModeFant : ctx.Settings.Interpolation.WeightingFunction.Support <0.1 ? WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor : ctx.Settings.Interpolation.WeightingFunction.Support <1.0 ? ctx.Settings.ScaleRatio> 1.0 ? WICBitmapInterpolationMode.WICBitmapInterpolationModeFant : WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor : ctx.Settings.Interpolation.WeightingFunction.Support> 1.0 ? ctx.Settings.ScaleRatio > 1.0 ? WICBitmapInterpolationMode.WICBitmapInterpolationModeHighQualityCubic :WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic : ctx.Settings.ScaleRatio > 1.0 ? WICBitmapInterpolationMode.WICBitmapInterpolationModeFant : WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear; var scaler = ctx.AddRef(Wic.Factory.CreateBitmapScaler()); scaler.Initialize(ctx.Source.WicSource, ow, oh, mode); ctx.Source = scaler.AsPixelSource(nameof(IWICBitmapScaler)); if (hybrid) { ctx.Settings.Crop = new Rectangle(0, 0, (int)ctx.Source.Width, (int)ctx.Source.Height); } }
public static void AddInternalFormatConverter(WicProcessingContext ctx) { var ifmt = ctx.Source.Format.FormatGuid; var ofmt = ifmt; bool linear = ctx.Settings.BlendingMode == GammaMode.Linear; if (MagicImageProcessor.EnableSimd) { if (ifmt == Consts.GUID_WICPixelFormat8bppGray) { ofmt = linear ? PixelFormat.Grey32BppLinearFloat.FormatGuid : Consts.GUID_WICPixelFormat32bppGrayFloat; } else if (ifmt == Consts.GUID_WICPixelFormat8bppY) { ofmt = linear ? PixelFormat.Y32BppLinearFloat.FormatGuid : PixelFormat.Y32BppFloat.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat24bppBGR) { ofmt = linear ? PixelFormat.Bgr96BppLinearFloat.FormatGuid : PixelFormat.Bgr96BppFloat.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat32bppBGRA || ifmt == Consts.GUID_WICPixelFormat32bppPBGRA) { ofmt = linear ? PixelFormat.Pbgra128BppLinearFloat.FormatGuid : PixelFormat.Pbgra128BppFloat.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat16bppCbCr) { ofmt = PixelFormat.CbCr64BppFloat.FormatGuid; } } else if (linear) { if (ifmt == Consts.GUID_WICPixelFormat8bppGray) { ofmt = PixelFormat.Grey16BppLinearUQ15.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat8bppY) { ofmt = PixelFormat.Y16BppLinearUQ15.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat24bppBGR) { ofmt = PixelFormat.Bgr48BppLinearUQ15.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat32bppBGRA) { ofmt = PixelFormat.Bgra64BppLinearUQ15.FormatGuid; } else if (ifmt == Consts.GUID_WICPixelFormat32bppPBGRA) { ofmt = PixelFormat.Pbgra64BppLinearUQ15.FormatGuid; } } if (ofmt == ifmt) { return; } ctx.Source = ctx.AddDispose(new FormatConversionTransform(ctx.Source, ofmt)); }
public static void AddColorspaceConverter(WicProcessingContext ctx) { if (ctx.SourceColorProfile == ctx.DestColorProfile) { if ((ctx.SourceColorProfile == ColorProfile.sRGB || ctx.SourceColorProfile == ColorProfile.sGrey) && ctx.SourceColorContext != null) { AddExternalFormatConverter(ctx); WicTransforms.AddColorspaceConverter(ctx); } return; } if (ctx.Source.Format.NumericRepresentation == PixelNumericRepresentation.Float && ctx.Source.Format.Colorspace != PixelColorspace.LinearRgb) { AddExternalFormatConverter(ctx); } AddInternalFormatConverter(ctx, forceLinear: true); if (ctx.Source.Format.ColorRepresentation != PixelColorRepresentation.Bgr) { return; } var matrix = ctx.SourceColorProfile.Matrix * ctx.DestColorProfile.InverseMatrix; if (matrix == default || matrix.IsIdentity) { return; } ctx.Source = new ColorMatrixTransformInternal(ctx.Source, matrix); }
private static void processImage(WicDecoder dec, WicProcessingContext ctx, Stream ostm) { using (var frm = new WicFrameReader(dec, ctx)) using (var met = new WicMetadataReader(frm)) { if (!ctx.Settings.Normalized) { ctx.Settings.Fixup((int)ctx.Width, (int)ctx.Height, ctx.IsRotated90); } ctx.Settings.HybridMode = HybridScaleMode.Turbo; //ctx.NeedsCache = true; using (var qsc = new WicNativeScaler(met)) using (var rot = new WicExifRotator(qsc)) using (var cac = new WicConditionalCache(rot)) using (var crp = new WicCropper(cac)) using (var pix = new WicPixelFormatConverter(crp)) using (var cmy = new WicCmykConverter(pix)) using (var res = new WicScaler(cmy)) using (var csc = new WicColorspaceConverter(res)) using (var mat = new WicMatteTransform(csc)) using (var pal = new WicPaletizer(mat, 256)) using (var enc = new WicEncoder(ostm.AsIStream(), ctx)) enc.WriteSource(pal); } }
private void init(IWICBitmapDecoder dec, WicProcessingContext ctx) { Decoder = AddRef(dec); ctx.ContainerFormat = dec.GetContainerFormat(); ctx.ContainerFrameCount = dec.GetFrameCount(); }
public WicDecoder(byte[] inBuffer, WicProcessingContext ctx) { var stm = AddRef(Wic.CreateStream()); stm.InitializeFromMemory(inBuffer, (uint)inBuffer.Length); init(checkDecoder(() => Wic.CreateDecoderFromStream(stm, null, WICDecodeOptions.WICDecodeMetadataCacheOnDemand)), ctx); }
public static void AddPlanarConverter(WicProcessingContext ctx) { var conv = ctx.AddRef(Wic.Factory.CreateFormatConverter()) as IWICPlanarFormatConverter; conv.Initialize(new[] { ctx.PlanarLumaSource.WicSource, ctx.PlanarChromaSource.WicSource }, 2, Consts.GUID_WICPixelFormat24bppBGR, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom); ctx.Source = conv.AsPixelSource(nameof(IWICPlanarFormatConverter)); ctx.PlanarChromaSource = ctx.PlanarLumaSource = null; }
public static void AddPixelFormatConverter(WicProcessingContext ctx, bool allowPbgra = true) { var curFormat = ctx.Source.Format; if (curFormat.ColorRepresentation == PixelColorRepresentation.Cmyk) { //TODO WIC doesn't support proper CMYKA conversion with color profile if (curFormat.AlphaRepresentation == PixelAlphaRepresentation.None) { // WIC doesn't support 16bpc CMYK conversion with color profile if (curFormat.BitsPerPixel == 64) { ctx.Source = ctx.AddDispose(new FormatConversionTransformInternal(ctx.Source, null, null, Consts.GUID_WICPixelFormat32bppCMYK)); } var trans = ctx.AddRef(Wic.Factory.CreateColorTransform()); if (trans.TryInitialize(ctx.Source.WicSource, ctx.SourceColorContext, ctx.DestColorContext, Consts.GUID_WICPixelFormat24bppBGR)) { ctx.Source = trans.AsPixelSource(nameof(IWICColorTransform)); curFormat = ctx.Source.Format; } } ctx.SourceColorContext = null; } var newFormat = PixelFormat.Cache[Consts.GUID_WICPixelFormat24bppBGR]; if (curFormat.AlphaRepresentation == PixelAlphaRepresentation.Associated && allowPbgra && ctx.Settings.BlendingMode != GammaMode.Linear && ctx.Settings.MatteColor.IsEmpty) { newFormat = PixelFormat.Cache[Consts.GUID_WICPixelFormat32bppPBGRA]; } else if (curFormat.AlphaRepresentation != PixelAlphaRepresentation.None) { newFormat = PixelFormat.Cache[Consts.GUID_WICPixelFormat32bppBGRA]; } else if (curFormat.ColorRepresentation == PixelColorRepresentation.Grey) { newFormat = PixelFormat.Cache[Consts.GUID_WICPixelFormat8bppGray]; } if (curFormat.FormatGuid == newFormat.FormatGuid) { return; } var conv = ctx.AddRef(Wic.Factory.CreateFormatConverter()); if (!conv.CanConvert(curFormat.FormatGuid, newFormat.FormatGuid)) { throw new NotSupportedException("Can't convert to destination pixel format"); } conv.Initialize(ctx.Source.WicSource, newFormat.FormatGuid, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom); ctx.Source = conv.AsPixelSource($"{nameof(IWICFormatConverter)}: {curFormat.Name}->{newFormat.Name}"); }
internal ProcessingPipeline(WicProcessingContext ctx) { Context = ctx; source = new Lazy <IPixelSource>(() => { MagicTransforms.AddExternalFormatConverter(Context); WicTransforms.AddPixelFormatConverter(Context, false); return(Context.Source.AsIPixelSource()); }); }
public static void ProcessImage(byte[] imgBuffer, Stream ostm, ProcessImageSettings s) { Contract.Requires <ArgumentNullException>(imgBuffer != null, nameof(imgBuffer)); Contract.Requires <ArgumentNullException>(ostm != null, nameof(ostm)); Contract.Requires <ArgumentException>(ostm.CanSeek && ostm.CanWrite, "Output Stream must allow Seek and Write"); using (var ctx = new WicProcessingContext(s)) using (var dec = new WicDecoder(imgBuffer, ctx)) processImage(dec, ctx, ostm); }
/// <summary>Constructs a new processing pipeline from which pixels can be retrieved.</summary> /// <param name="imgStream">A stream containing a supported input image container.</param> /// <param name="settings">The settings for this processing operation.</param> /// <returns>A <see cref="ProcessingPipeline" /> containing the <see cref="IPixelSource" />, settings used, and basic instrumentation for the pipeline.</returns> public static ProcessingPipeline BuildPipeline(Stream imgStream, ProcessImageSettings settings) { checkInStream(imgStream); var ctx = new WicProcessingContext(settings); var dec = new WicDecoder(imgStream, ctx); buildPipeline(ctx, false); return(new ProcessingPipeline(ctx)); }
public ImageFileInfo(byte[] imgBuffer, DateTime lastModified) { Contract.Requires <ArgumentNullException>(imgBuffer != null, nameof(imgBuffer)); using (var ctx = new WicProcessingContext(new ProcessImageSettings())) using (var dec = new WicDecoder(imgBuffer, ctx)) loadInfo(dec, ctx); FileSize = imgBuffer.Length; FileDate = lastModified; }
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; }
public static void AddPad(WicProcessingContext ctx) { if (ctx.Settings.InnerRect == ctx.Settings.OuterRect) { return; } AddExternalFormatConverter(ctx); ctx.Source = new PadTransformInternal(ctx.Source, ctx.Settings.MatteColor, ctx.Settings.InnerRect, ctx.Settings.OuterRect); }
public static void AddCropper(WicProcessingContext ctx) { if (ctx.Settings.Crop == new Rectangle(0, 0, (int)ctx.Source.Width, (int)ctx.Source.Height)) { return; } var cropper = ctx.AddRef(Wic.Factory.CreateBitmapClipper()); cropper.Initialize(ctx.Source.WicSource, ctx.Settings.Crop.ToWicRect()); ctx.Source = cropper.AsPixelSource(nameof(IWICBitmapClipper)); }
public static void AddExifRotator(WicProcessingContext ctx) { if (ctx.DecoderFrame.ExifOrientation == Orientation.Normal) { return; } var rotator = ctx.AddRef(Wic.Factory.CreateBitmapFlipRotator()); rotator.Initialize(ctx.Source.WicSource, ctx.DecoderFrame.ExifOrientation.ToWicTransformOptions()); ctx.Source = rotator.AsPixelSource(nameof(IWICBitmapFlipRotator), !ctx.DecoderFrame.SupportsPlanarPipeline && !ctx.DecoderFrame.SupportsNativeTransform); }
public static void ProcessImage(Stream istm, Stream ostm, ProcessImageSettings s) { Contract.Requires <ArgumentNullException>(istm != null, nameof(istm)); Contract.Requires <ArgumentNullException>(ostm != null, nameof(ostm)); Contract.Requires <ArgumentException>(istm.CanSeek && istm.CanRead, "Input Stream must allow Seek and Read"); Contract.Requires <ArgumentException>(ostm.CanSeek && ostm.CanWrite, "Output Stream must allow Seek and Write"); Contract.Assume(istm.Position < istm.Length, "Input Stream Position is at the end. Did you forget to Seek?"); using (var ctx = new WicProcessingContext(s)) using (var dec = new WicDecoder(istm, ctx)) processImage(dec, ctx, ostm); }
/// <summary>All-in-one processing of an image according to the specified <paramref name="settings" />.</summary> /// <param name="imgStream">A stream containing a supported input image container.</param> /// <param name="outStream">The stream to which the output image will be written.</param> /// <param name="settings">The settings for this processing operation.</param> /// <returns>A <see cref="ProcessImageResult" /> containing the settings used and basic instrumentation for the pipeline.</returns> public static ProcessImageResult ProcessImage(Stream imgStream, Stream outStream, ProcessImageSettings settings) { checkInStream(imgStream); checkOutStream(outStream); using (var ctx = new WicProcessingContext(settings)) { var dec = new WicDecoder(imgStream, ctx); buildPipeline(ctx); return(executePipeline(ctx, outStream)); } }
private static ProcessImageResult executePipeline(WicProcessingContext ctx, Stream ostm) { WicTransforms.AddIndexedColorConverter(ctx); var enc = new WicEncoder(ctx, ostm.AsIStream()); enc.WriteSource(ctx); return(new ProcessImageResult { Settings = ctx.UsedSettings, Stats = ctx.Stats }); }
public static void AddColorspaceConverter(WicProcessingContext ctx) { if (ctx.SourceColorContext == null) { return; } var trans = ctx.AddRef(Wic.Factory.CreateColorTransform()); trans.Initialize(ctx.Source.WicSource, ctx.SourceColorContext, ctx.DestColorContext, ctx.Source.Format.FormatGuid); ctx.Source = trans.AsPixelSource(nameof(IWICColorTransform)); }
public static void AddPixelFormatConverter(WicProcessingContext ctx) { var oldFormat = ctx.Source.Format; if (oldFormat.ColorRepresentation == PixelColorRepresentation.Cmyk) { //TODO WIC doesn't support proper CMYKA conversion with color profile if (oldFormat.AlphaRepresentation == PixelAlphaRepresentation.None) { // WIC doesn't support 16bpc CMYK conversion with color profile if (oldFormat.BitsPerPixel == 64) { ctx.Source = new FormatConversionTransform(ctx.Source, Consts.GUID_WICPixelFormat32bppCMYK); } var trans = ctx.AddRef(Wic.Factory.CreateColorTransform()); if (trans.TryInitialize(ctx.Source.WicSource, ctx.SourceColorContext, ctx.DestColorContext, Consts.GUID_WICPixelFormat24bppBGR)) { ctx.Source = trans.AsPixelSource(nameof(IWICColorTransform)); oldFormat = ctx.Source.Format; } } ctx.SourceColorContext = null; } var newFormat = Consts.GUID_WICPixelFormat24bppBGR; if (oldFormat.AlphaRepresentation != PixelAlphaRepresentation.None) { newFormat = oldFormat.AlphaRepresentation == PixelAlphaRepresentation.Associated ? Consts.GUID_WICPixelFormat32bppPBGRA : Consts.GUID_WICPixelFormat32bppBGRA; } else if (oldFormat.ColorRepresentation == PixelColorRepresentation.Grey) { newFormat = Consts.GUID_WICPixelFormat8bppGray; } if (oldFormat.FormatGuid == newFormat) { return; } var conv = ctx.AddRef(Wic.Factory.CreateFormatConverter()); if (!conv.CanConvert(oldFormat.FormatGuid, newFormat)) { throw new NotSupportedException("Can't convert to destination pixel format"); } conv.Initialize(ctx.Source.WicSource, newFormat, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom); ctx.Source = conv.AsPixelSource(nameof(IWICFormatConverter)); }
/// <summary>Constructs a new processing pipeline from which pixels can be retrieved.</summary> /// <param name="imgSource">A custom pixel source to use as input.</param> /// <param name="settings">The settings for this processing operation.</param> /// <returns>A <see cref="ProcessingPipeline" /> containing the <see cref="IPixelSource" />, settings used, and basic instrumentation for the pipeline.</returns> public static ProcessingPipeline BuildPipeline(IPixelSource imgSource, ProcessImageSettings settings) { if (imgSource is null) { throw new ArgumentNullException(nameof(imgSource)); } var ctx = new WicProcessingContext(settings); var dec = new WicDecoder(imgSource, ctx); buildPipeline(ctx, false); return(new ProcessingPipeline(ctx)); }