public void Scale(int boxSize, WICBitmapInterpolationMode mode = WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor, WicBitmapScaleOptions options = WicBitmapScaleOptions.Default) { if (boxSize <= 0) { throw new ArgumentOutOfRangeException(nameof(boxSize)); } if (Width > Height) { Scale(boxSize, null, mode, options); return; } Scale(null, boxSize, mode, options); }
public virtual int Initialize( IWICBitmapSource pISource, uint uiWidth, uint uiHeight, WICBitmapInterpolationMode mode ) { var fp = GetFunctionPointer(8); if (m_InitializeFunc == null) { m_InitializeFunc = (InitializeFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(InitializeFunc)); } return(m_InitializeFunc(m_ptr, pISource != null ? pISource.Ptr : IntPtr.Zero, uiWidth, uiHeight, mode)); }
public int Initialize([NativeTypeName("IWICBitmapSource *")] IWICBitmapSource *pISource, [NativeTypeName("UINT")] uint uiWidth, [NativeTypeName("UINT")] uint uiHeight, WICBitmapInterpolationMode mode) { return(((delegate * unmanaged <IWICBitmapScaler *, IWICBitmapSource *, uint, uint, WICBitmapInterpolationMode, int>)(lpVtbl[8]))((IWICBitmapScaler *)Unsafe.AsPointer(ref this), pISource, uiWidth, uiHeight, mode)); }
public void Scale(int?width, int?height, WICBitmapInterpolationMode mode = WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor, WicBitmapScaleOptions options = WicBitmapScaleOptions.Default) { if (!width.HasValue && !height.HasValue) { return; } if (width.HasValue && width.Value <= 0) { throw new ArgumentOutOfRangeException(nameof(width)); } if (height.HasValue && height.Value <= 0) { throw new ArgumentOutOfRangeException(nameof(height)); } int neww; int newh; if (width.HasValue && height.HasValue) { neww = width.Value; newh = height.Value; } else { int w = Width; int h = Height; if (w == 0 || h == 0) { return; } if (width.HasValue) { if ((options & WicBitmapScaleOptions.DownOnly) == WicBitmapScaleOptions.DownOnly) { if (width.Value > w) { return; } } neww = width.Value; newh = width.Value * h / w; } else // height.HasValue { if ((options & WicBitmapScaleOptions.DownOnly) == WicBitmapScaleOptions.DownOnly) { if (height.Value > h) { return; } } newh = height.Value; neww = height.Value * w / h; } } if (neww == 0 || newh == 0) { return; } var clip = WICImagingFactory.CreateBitmapScaler(); clip.Object.Initialize(_comObject.Object, neww, newh, mode).ThrowOnError(); _comObject?.Dispose(); _comObject = clip; }
public HRESULT Initialize(IWICBitmapSource *pISource, uint uiWidth, uint uiHeight, WICBitmapInterpolationMode mode) { return(((delegate * unmanaged <IWICBitmapScaler *, IWICBitmapSource *, uint, uint, WICBitmapInterpolationMode, int>)(lpVtbl[8]))((IWICBitmapScaler *)Unsafe.AsPointer(ref this), pISource, uiWidth, uiHeight, mode)); }
public static void Initialize(this IWICBitmapScaler bitmapScaler, IWICBitmapSource pISource, Size size, WICBitmapInterpolationMode mode) { bitmapScaler.Initialize(pISource, size.Width, size.Height, mode); }
/// <summary> /// Decodes the image in byte[] data, performs the image proccessing, and encodes it to job.Dest /// </summary> /// <param name="data">The buffer containing the encoded image file</param> /// <param name="lData">The number of bytes to read</param> /// <param name="job"></param> /// <param name="supportsTransparency"></param> /// <returns></returns> protected virtual RequestedAction BuildJobWic(byte[] data, long lData, ImageJob job, bool supportsTransparency) { ResizeSettings settings = job.Settings; ResizeSettings q = settings; string path = job.SourcePathData; //A list of COM objects to destroy List <object> com = new List <object>(); try { //Create the factory IWICComponentFactory factory = (IWICComponentFactory) new WICImagingFactory(); com.Add(factory); //Wrap the byte[] with a IWICStream instance var streamWrapper = factory.CreateStream(); streamWrapper.InitializeFromMemory(data, (uint)lData); com.Add(streamWrapper); var decoder = factory.CreateDecoderFromStream(streamWrapper, null, WICDecodeOptions.WICDecodeMetadataCacheOnLoad); com.Add(decoder); //Figure out which frame to work with int frameIndex = 0; if (!string.IsNullOrEmpty(q["page"]) && !int.TryParse(q["page"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex)) { if (!string.IsNullOrEmpty(q["frame"]) && !int.TryParse(q["frame"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex)) { frameIndex = 0; } } //So users can use 1-based numbers frameIndex--; if (frameIndex > 0) { int frameCount = (int)decoder.GetFrameCount(); //Don't let the user go past the end. if (frameIndex >= frameCount) { frameIndex = frameCount - 1; } } IWICBitmapFrameDecode frame = decoder.GetFrame((uint)Math.Max(0, frameIndex)); com.Add(frame); WICBitmapInterpolationMode interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeFant; if ("nearest".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) { interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor; } if ("bicubic".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) { interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic; } if ("linear".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) { interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear; } if ("nearestneighbor".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) { interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear; } //Find the original image size uint origWidth, origHeight; frame.GetSize(out origWidth, out origHeight); Size orig = new Size((int)origWidth, (int)origHeight); Guid pixelFormat; frame.GetPixelFormat(out pixelFormat); //Calculate the new size of the image and the canvas. ImageState state = new ImageState(settings, orig, true); c.CurrentImageBuilder.Process(state); Rectangle imageDest = PolygonMath.ToRectangle(PolygonMath.GetBoundingBox(state.layout["image"])); IWICBitmapSource imageData = frame; //Are we cropping? then daisy-chain a clipper if (state.copyRect.Left != 0 || state.copyRect.Top != 0 || state.copyRect.Width != state.originalSize.Width || state.copyRect.Height != state.originalSize.Height) { //Cropping is absurdly slow... 4x slower than resizing! //Cropping after resizing (unintuitively) is faster. if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height) { double sx = (double)imageDest.Width / (double)state.copyRect.Width; double sy = (double)imageDest.Height / (double)state.copyRect.Height; uint uncroppedDestWidth = (uint)Math.Round(sx * state.originalSize.Width); uint uncroppedDestHeight = (uint)Math.Round(sy * state.originalSize.Height); var scaler = factory.CreateBitmapScaler(); scaler.Initialize(imageData, uncroppedDestWidth, uncroppedDestHeight, interpolationMode); com.Add(scaler); //TODO: cropping is not consistent with GDI. var clipper = factory.CreateBitmapClipper(); clipper.Initialize(scaler, new WICRect { X = (int)Math.Floor((double)state.copyRect.X * sx), Y = (int)Math.Floor((double)state.copyRect.Y * sy), Width = imageDest.Width, Height = imageDest.Height }); com.Add(clipper); imageData = clipper; } else { var clipper = factory.CreateBitmapClipper(); clipper.Initialize(imageData, new WICRect { X = (int)state.copyRect.X, Y = (int)state.copyRect.Y, Width = (int)state.copyRect.Width, Height = (int)state.copyRect.Height }); com.Add(clipper); imageData = clipper; } //If we're scaling but not cropping. } else if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height) { var scaler = factory.CreateBitmapScaler(); scaler.Initialize(imageData, (uint)imageDest.Width, (uint)imageDest.Height, interpolationMode); com.Add(scaler); imageData = scaler; } //Are we padding? Then we have to do an intermediate write. if (state.destSize.Width != imageDest.Width || state.destSize.Height != imageDest.Height) { byte[] bgcolor = ConversionUtils.ConvertColor(job.Settings.BackgroundColor, pixelFormat); for (int i = 0; i < bgcolor.Length; i++) { bgcolor[i] = 255; //White } var padder = new WicBitmapPadder(imageData, imageDest.X, imageDest.Y, state.destSize.Width - (imageDest.X + imageDest.Width), state.destSize.Height - (imageDest.Y + imageDest.Height), bgcolor, null); imageData = padder; } //Now encode imageData and be done with it... return(Encode(factory, imageData, imageDest.Size, job)); } finally { //Manually cleanup all the com reference counts, aggressively while (com.Count > 0) { Marshal.ReleaseComObject(com[com.Count - 1]); //In reverse order, so no item is ever deleted out from under another. com.RemoveAt(com.Count - 1); } } }