Example #1
0
        /// <summary>
        /// Adds padding to a bitmap, optionally cropping it at the same time.
        /// </summary>
        /// <param name="s"></param>
        /// <param name="left"></param>
        /// <param name="top"></param>
        /// <param name="right"></param>
        /// <param name="bottom"></param>
        /// <param name="bgcolor"></param>
        /// <param name="crop"></param>
        public WicBitmapPadder(IWICBitmapSource s, int left, int top, int right, int bottom, byte[] bgcolor, WICRect crop)
        {
            this.s = s;
            this.left = left;
            this.right = right;
            this.bottom = bottom;
            this.top = top;
            this.bgcolor = bgcolor;
            this.crop = crop;

            Guid pf;
            s.GetPixelFormat(out pf);
            if (bgcolor.Length != ConversionUtils.BytesPerPixel(pf)) throw new ArgumentException("bgcolor length must match the format bytes per pixel");
        }
        public static SlimDX.Direct2D.Bitmap CreateBitmapFromWicBitmap(IWICBitmapSource source, BitmapProperties bitmapProperties, RenderTarget renderTarget)
        {
            var pBitmap = IntPtr.Zero;
            SlimDX.Direct2D.Bitmap bmp = null;

            var pRenderTarget = Marshal.GetObjectForIUnknown(renderTarget.ComPointer) as ID2D1RenderTarget;

            int hr = pRenderTarget.CreateBitmapFromWicBitmap(source, ref bitmapProperties, out pBitmap);

            if (hr != 0)
                goto cleanup;
          
            bmp = SlimDX.Direct2D.Bitmap.FromPointer(pBitmap);
           
cleanup:
            Marshal.Release(pBitmap);
            Marshal.ReleaseComObject(pRenderTarget);

            return bmp;
        }
Example #3
0
 public extern IWICBitmap CreateBitmapFromSourceRect([In, MarshalAs(UnmanagedType.Interface)] IWICBitmapSource pIBitmapSource, [In] uint X, [In] uint Y, [In] uint Width, [In] uint Height);
        public static bool TryGetPreview(this IWICBitmapDecoder dec, out IWICBitmapSource pvw)
        {
            int hr = ProxyFunctions.GetPreview(dec, out pvw);

            return(hr >= 0);
        }
 public void GetThumbnail(out IWICBitmapSource ppIThumbnail)
 {
     Log.Trace("GetThumbnail called");
     var guid = Guid.Empty;
     var pPreviewDecoder = RW2BitmapDecoder.GetImagingFactory().CreateDecoderFromStream(
                         new StreamComWrapper(new MemoryStream(exif.Thumbnail)), ref guid,
                         WICDecodeOptions.WICDecodeMetadataCacheOnDemand);
     IWICBitmapFrameDecode pPreviewFrame;
     pPreviewDecoder.GetFrame(0, out pPreviewFrame);
     ppIThumbnail = pPreviewFrame;
     Log.Trace("GetThumbnail finished");
 }
Example #6
0
        public static IComObject <IWICBitmap> CreateBitmapFromSource(this IWICImagingFactory factory, IWICBitmapSource source, WICBitmapCreateCacheOption option = WICBitmapCreateCacheOption.WICBitmapNoCache)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

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

            factory.CreateBitmapFromSource(source, option, out var value).ThrowOnError();
            return(new ComObject <IWICBitmap>(value));
        }
Example #7
0
 internal static extern int CopyPixels(IWICBitmapSource bitmap, IntPtr rect, uint cbStride, uint cbBufferSize, IntPtr pvPixels);
Example #8
0
 public ArgbImage(IWICImagingFactory factory, IWICBitmapSource bitmapSource) : base(factory, bitmapSource, ArgbImage.WicImageFormat)
 {
 }
Example #9
0
 public static uint GetStride(IWICBitmapSource source)
 {
     uint w, h;
     source.GetSize(out w, out h);
     Guid format;
     source.GetPixelFormat(out format);
     uint dword = 4;
     uint stride = (uint)BytesPerPixel(format) * w; //1bpp, 2bpp, 4 bpp all take one byte? Not sure how to handle those.
     stride = ((stride + dword - 1) / dword) * dword; //Round up to multiple of 4.
     return stride;
 }
 public WicLinearFormatConverter(IWICBitmapSource source, Guid dstFormat) : base(source, dstFormat)
 {
 }
 public WicFormatConverterBase(IWICBitmapSource source, Guid dstFormat) : base(source)
 {
     OutFormat = dstFormat;
     LineBuff  = new byte[Stride];
     HasAlpha  = Format == Consts.GUID_WICPixelFormat64bppBGRA || Format == Consts.GUID_WICPixelFormat32bppBGRA;
 }
Example #12
0
        public static (int Left, int Top, int Width, int Height, bool Alpha, bool FullScreen, GifDisposalMethod Disposal) GetGifFrameInfo(WicGifContainer cont, IWICBitmapSource frame, IWICMetadataQueryReader meta)
        {
            frame.GetSize(out uint width, out uint height);

            int  left = 0, top = 0;
            var  disp  = ((GifDisposalMethod)meta.GetValueOrDefault <byte>(Wic.Metadata.Gif.FrameDisposal)).Clamp();
            bool trans = meta.GetValueOrDefault <bool>(Wic.Metadata.Gif.TransparencyFlag);
            bool full  = width == cont.ScreenWidth && height == cont.ScreenHeight;

            if (!full)
            {
                left = meta.GetValueOrDefault <ushort>(Wic.Metadata.Gif.FrameLeft);
                top  = meta.GetValueOrDefault <ushort>(Wic.Metadata.Gif.FrameTop);
            }

            return(left, top, (int)width, (int)height, trans, full, disp);
        }
Example #13
0
        public void EncodeToStream(IWICComponentFactory factory, IWICBitmapSource data, Size imageSize, IStream outputStream)
        {
            //A list of COM objects to destroy
            List <object> com = new List <object>();

            try {
                //Find the GUID of the destination format
                Guid guidEncoder = GetOutputFormatWicGuid();

                //Find out the data's pixel format
                Guid pFormat = Guid.Empty;
                data.GetPixelFormat(out pFormat);

                //Create the encoder
                var encoder = factory.CreateEncoder(guidEncoder, null);
                com.Add(encoder);
                //And initialize it
                encoder.Initialize(outputStream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                // Create the output frame and property bag
                IWICBitmapFrameEncode outputFrame;
                var propertyBagArray = new IPropertyBag2[1];
                encoder.CreateNewFrame(out outputFrame, propertyBagArray); //An array is used instead of an out parameter... I have no idea why
                com.Add(outputFrame);
                //The property bag is a COM object...
                var propBag = propertyBagArray[0];
                com.Add(propBag);

                //Adjust encoder settings if it's a jpegs
                if (guidEncoder.Equals(Consts.GUID_ContainerFormatJpeg))
                {
                    //Jpeg
                    //ImageQuality 0..1
                    //"JpegYCrCbSubsampling"  WICJpegYCrCbSubsamplingOption.

                    //Configure encoder settings (see http://msdn.microsoft.com/en-us/library/windows/desktop/ee719871(v=vs.85).aspx#encoderoptions)
                    var qualityOption = new PROPBAG2[1];
                    qualityOption[0].pstrName = "ImageQuality";

                    propBag.Write(1, qualityOption, new object[] { ((float)Math.Max(0, Math.Min(100, Quality))) / 100 });

                    WICJpegYCrCbSubsamplingOption subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsamplingDefault;
                    //411 NOT SUPPPORTED BY WIC - only by freeimage
                    if ("420".Equals(Subsampling))
                    {
                        subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling420;
                    }
                    if ("422".Equals(Subsampling))
                    {
                        subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling422;
                    }
                    if ("444".Equals(Subsampling))
                    {
                        subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling444;
                    }

                    if (subsampling != WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsamplingDefault)
                    {
                        var samplingOption = new PROPBAG2[1];
                        samplingOption[0].pstrName = "JpegYCrCbSubsampling";
                        samplingOption[0].vt       = VarEnum.VT_UI1;
                        propBag.Write(1, samplingOption, new object[] { (byte)subsampling });
                    }
                }
                //PNG interlace
                if (guidEncoder.Equals(Consts.GUID_ContainerFormatPng))
                {
                    var interlaceOption = new PROPBAG2[1];
                    interlaceOption[0].pstrName = "InterlaceOption";

                    propBag.Write(1, interlaceOption, new object[] { Interlace ?? false });
                }

                //Apply the property bag
                outputFrame.Initialize(propBag);


                //Convert the bitmap to the correct pixel format for encoding.

                //Jpeg: encodes as GUID_WICPixelFormat24bppBGR or GUID_WICPixelFormat8bppGray.
                //If the original pixel format has an alpha chanel, we need to specify a matte color.
                //UPDATE - IWICFormatConverter doesn't let you specify a matte color. Disabling code
                if (false && guidEncoder.Equals(Consts.GUID_ContainerFormatJpeg))
                {
                    ConversionUtils.HasAlphaAbility(pFormat);
                    var conv = factory.CreateFormatConverter();
                    com.Add(conv);
                    if (conv.CanConvert(pFormat, Consts.GUID_WICPixelFormat24bppBGR))
                    {
                        /*dither, pIPalette, alphaThresholdPercent, and paletteTranslate are used to mitigate color loss when
                         * converting to a reduced bit-depth format. For conversions that do not need these settings, the
                         * following parameters values should be used: dither set to WICBitmapDitherTypeNone, pIPalette set to NULL,
                         * alphaThresholdPercent set to 0.0f, and paletteTranslate set to WICBitmapPaletteTypeCustom.*/
                        conv.Initialize(data, Consts.GUID_WICPixelFormat24bppBGR, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0f, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                        data = conv;
                        //Oops, we didn't do anything - there's no way to specify a matte color!
                    }
                }

                //GIF encodes as GUID_WICPixelFormat8bppIndexed
                //If the current format is > 8bpp, quantization may be required, and we may need to manually build the palette with Median Cut.

                //PNG encodeds as EVERYTHING! Way too many formats supported.
                // If the user is specifying a colors setting, we need to
                // convert to GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat2bppIndexed, or GUID_WICPixelFormat1bppIndexed

                if ((guidEncoder.Equals(Consts.GUID_ContainerFormatPng) && this.Colors != -1) || (guidEncoder.Equals(Consts.GUID_ContainerFormatGif)))
                {
                    Guid target = Consts.GUID_WICPixelFormat8bppIndexed;

                    int colors = this.Colors;

                    if (colors > 0 && guidEncoder.Equals(Consts.GUID_ContainerFormatPng))
                    {
                        if (colors <= 2)
                        {
                            target = Consts.GUID_WICPixelFormat1bppIndexed;
                        }
                        if (colors <= 4)
                        {
                            target = Consts.GUID_WICPixelFormat2bppIndexed;
                        }
                        if (colors <= 32)
                        {
                            target = Consts.GUID_WICPixelFormat4bppIndexed;
                        }
                    }
                    if (colors < 0)
                    {
                        colors = 256;
                    }
                    if (colors < 2)
                    {
                        colors = 2;
                    }
                    if (colors > 256)
                    {
                        colors = 256;
                    }

                    var conv = factory.CreateFormatConverter();
                    com.Add(conv);
                    if (conv.CanConvert(pFormat, target))
                    {
                        var palette = factory.CreatePalette();
                        com.Add(palette);
                        palette.InitializeFromBitmap(data, (uint)colors, true);

                        /*dither, pIPalette, alphaThresholdPercent, and paletteTranslate are used to mitigate color loss when
                         * converting to a reduced bit-depth format. For conversions that do not need these settings, the
                         * following parameters values should be used: dither set to WICBitmapDitherTypeNone, pIPalette set to NULL,
                         * alphaThresholdPercent set to 0.0f, and paletteTranslate set to WICBitmapPaletteTypeCustom.*/
                        conv.Initialize(data, target, this.Dither ? WICBitmapDitherType.WICBitmapDitherTypeErrorDiffusion :  WICBitmapDitherType.WICBitmapDitherTypeNone,
                                        palette, 50.0f, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                        data = conv;
                    }
                }

                //Get size
                uint fw, fh;
                data.GetSize(out fw, out fh);

                //Set destination frame size
                outputFrame.SetSize(fw, fh);

                // Write the data to the output frame
                outputFrame.WriteSource(data, null);
                outputFrame.Commit();
                encoder.Commit();
            } 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);
                }
            }
        }
Example #14
0
        public static IComObject <T> CreateBitmapFromWicBitmap <T>(this ID2D1DeviceContext context, IWICBitmapSource source, D2D1_BITMAP_PROPERTIES1?properties = null) where T : ID2D1Bitmap1
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

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

            using (var mem = properties.StructureToMemory())
            {
                context.CreateBitmapFromWicBitmap(source, mem.Pointer, out ID2D1Bitmap1 bmp).ThrowOnError();
                return(new ComObject <T>((T)bmp));
            }
        }
Example #15
0
        public void GetThumbnail(out IWICBitmapSource ppIThumbnail)
        {
            Log.Trace("GetThumbnail called");

            try
            {
                var guid = Guid.Empty;

                lock (this)
                {
                    var pPreviewDecoder = GetImagingFactory().CreateDecoderFromStream(
                                        new StreamComWrapper(new MemoryStream(exif.Thumbnail)), ref guid,
                                        WICDecodeOptions.WICDecodeMetadataCacheOnDemand);
                    IWICBitmapFrameDecode pPreviewFrame;
                    pPreviewDecoder.GetFrame(0, out pPreviewFrame);
                    ppIThumbnail = pPreviewFrame;
                }
                Log.Trace("GetThumbnail finished");
            }
            catch (Exception e)
            {
                Log.Error("GetThumbnail failed: " + e);
                throw;
            }
        }
Example #16
0
 public void GetPreview(out IWICBitmapSource ppIBitmapSource)
 {
     Log.Trace("GetPreview called");
     GetThumbnail(out ppIBitmapSource);
 }
Example #17
0
        public WicConvolution(IWICBitmapSource source, KernelMap <TWeight> mapx, KernelMap <TWeight> mapy, bool bufferSource = false) : base(source)
        {
            if (Format.FormatGuid == Consts.GUID_WICPixelFormat32bppPBGRA)
            {
                Processor = new Convolver4ChanByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat32bppBGRA)
            {
                Processor = new ConvolverBgraByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat24bppBGR)
            {
                Processor = new ConvolverBgrByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat16bppCbCr)
            {
                Processor = new Convolver2ChanByte();
            }
            else if (Format.FormatGuid == Consts.GUID_WICPixelFormat8bppGray || Format.FormatGuid == Consts.GUID_WICPixelFormat8bppY)
            {
                Processor = new Convolver1ChanByte();
            }
            else if (Format == PixelFormat.Pbgra64BppLinearUQ15)
            {
                Processor = new Convolver4ChanUQ15();
            }
            else if (Format == PixelFormat.Bgra64BppLinearUQ15)
            {
                Processor = new ConvolverBgraUQ15();
            }
            else if (Format == PixelFormat.Bgr48BppLinearUQ15)
            {
                Processor = new ConvolverBgrUQ15();
            }
            else if (Format == PixelFormat.Grey16BppLinearUQ15 || Format == PixelFormat.Y16BppLinearUQ15)
            {
                Processor = new Convolver1ChanUQ15();
            }
            else if (Format == PixelFormat.Pbgra128BppLinearFloat || Format == PixelFormat.Pbgra128BppFloat)
            {
                Processor = new Convolver4ChanFloat();
            }
            else if (Format == PixelFormat.Bgr96BppLinearFloat || Format == PixelFormat.Bgr96BppFloat)
            {
                Processor = new Convolver3ChanFloat();
            }
            else if (Format == PixelFormat.CbCr64BppFloat)
            {
                Processor = new Convolver2ChanFloat();
            }
            else if (Format == PixelFormat.Grey32BppLinearFloat || Format.FormatGuid == Consts.GUID_WICPixelFormat32bppGrayFloat || Format == PixelFormat.Y32BppLinearFloat || Format == PixelFormat.Y32BppFloat)
            {
                Processor = new Convolver1ChanFloat();
            }
            else
            {
                throw new NotSupportedException("Unsupported pixel format");
            }

            BufferSource = bufferSource;
            OutWidth     = (uint)mapx.OutPixels;
            OutHeight    = (uint)mapy.OutPixels;
            SourceRect   = new WICRect {
                Width = (int)Width, Height = 1
            };
            XMap = mapx;
            YMap = mapy;

            IntBpp       = Bpp / Unsafe.SizeOf <TPixel>() * Unsafe.SizeOf <TWeight>();
            IntStride    = mapy.Samples * IntBpp;
            IntStartLine = -mapy.Samples;

            int lineBuffLen = (bufferSource ? mapy.Samples : 1) * (int)Stride;
            int intBuffLen  = mapx.OutPixels * IntStride;

            LineBuff = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(lineBuffLen), 0, lineBuffLen);
            IntBuff  = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(intBuffLen), 0, intBuffLen);
        }
 public WicCustomPixelFormatConverter(IWICBitmapSource source, Guid dstFormat) : base(source)
 {
     InFormat  = PixelFormat.Cache[source.GetPixelFormat()];
     OutFormat = PixelFormat.Cache[dstFormat];
     LineBuff  = ArrayPool <byte> .Shared.Rent((int)Stride);
 }
Example #19
0
 public static WICSize GetSize(this IWICBitmapSource bitmapSource)
 {
     bitmapSource.GetSize(out int width, out int height);
     return(new WICSize(width, height));
 }
Example #20
0
 public void GetPreview(out IWICBitmapSource ppIBitmapSource)
 {
     Log.Trace("GetPreview called");
     GetThumbnail(out ppIBitmapSource);
 }
Example #21
0
        public void EncodeToStream(IWICComponentFactory factory, IWICBitmapSource data, IStream outputStream)
        {
            //A list of COM objects to destroy
            List <object> com = new List <object>();

            try
            {
                //Find the GUID of the destination format
                Guid guidEncoder = Consts.GUID_ContainerFormatJpeg;

                //Find out the data's pixel format
                Guid pFormat = Guid.Empty;
                data.GetPixelFormat(out pFormat);

                //Create the encoder
                var encoder = factory.CreateEncoder(guidEncoder, null);
                com.Add(encoder);
                //And initialize it
                encoder.Initialize(outputStream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                // Create the output frame and property bag
                IWICBitmapFrameEncode outputFrame;
                var propertyBagArray = new IPropertyBag2[1];
                encoder.CreateNewFrame(out outputFrame, propertyBagArray); //An array is used instead of an out parameter... I have no idea why
                com.Add(outputFrame);
                //The property bag is a COM object...
                var propBag = propertyBagArray[0];
                com.Add(propBag);

                //Adjust encoder settings if it's a jpegs
                if (guidEncoder.Equals(Consts.GUID_ContainerFormatJpeg))
                {
                    //Configure encoder settings (see http://msdn.microsoft.com/en-us/library/windows/desktop/ee719871(v=vs.85).aspx#encoderoptions)
                    var qualityOption = new PROPBAG2[1];
                    qualityOption[0].pstrName = "ImageQuality";
                    qualityOption[0].vt       = VarEnum.VT_R4;
                    object qualityValue = ((float)90) / 100;

                    propBag.Write(1, qualityOption, new object[] { qualityValue });
                }

                //Apply the property bag
                outputFrame.Initialize(propBag);


                //Get size
                uint fw, fh;
                data.GetSize(out fw, out fh);

                //Set destination frame size
                outputFrame.SetSize(fw, fh);

                // Write the data to the output frame
                outputFrame.WriteSource(data, null);
                outputFrame.Commit();
                encoder.Commit();
            }
            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);
                }
            }
        }
Example #22
0
 public WicTransform(IWICBitmapFrameDecode frm, IWICBitmapSource src, WicProcessingContext ctx)
 {
     Frame   = frm;
     Source  = src;
     Context = ctx;
 }
Example #23
0
 public WicUnsharpMask16bpc(IWICBitmapSource source, KernelMap mapx, KernelMap mapy, UnsharpMaskSettings ss) : base(source, mapx, mapy, true)
 {
     sharpenSettings = ss;
     blurBuff        = new ushort[Stride];
 }
Example #24
0
        public void EncodeToStream(IWICComponentFactory factory, IWICBitmapSource data, Size imageSize, IStream outputStream)
        {
            //A list of COM objects to destroy
            List<object> com = new List<object>();
            try {

                //Find the GUID of the destination format
                Guid guidEncoder = GetOutputFormatWicGuid();

                //Find out the data's pixel format
                Guid pFormat = Guid.Empty;
                data.GetPixelFormat(out pFormat);

                //Create the encoder
                var encoder = factory.CreateEncoder(guidEncoder, null);
                com.Add(encoder);
                //And initialize it
                encoder.Initialize(outputStream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                // Create the output frame and property bag
                IWICBitmapFrameEncode outputFrame;
                var propertyBagArray = new IPropertyBag2[1];
                encoder.CreateNewFrame(out outputFrame, propertyBagArray); //An array is used instead of an out parameter... I have no idea why
                com.Add(outputFrame);
                //The property bag is a COM object...
                var propBag = propertyBagArray[0];
                com.Add(propBag);

                //Adjust encoder settings if it's a jpegs
                if (guidEncoder.Equals(Consts.GUID_ContainerFormatJpeg)) {
                    //Jpeg
                    //ImageQuality 0..1
                    //"JpegYCrCbSubsampling"  WICJpegYCrCbSubsamplingOption.

                    //Configure encoder settings (see http://msdn.microsoft.com/en-us/library/windows/desktop/ee719871(v=vs.85).aspx#encoderoptions)
                    var qualityOption = new PROPBAG2[1];
                    qualityOption[0].pstrName = "ImageQuality";

                    propBag.Write(1, qualityOption, new object[] { ((float)Math.Max(0,Math.Min(100,Quality))) / 100 });

                    WICJpegYCrCbSubsamplingOption subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsamplingDefault;
                    //411 NOT SUPPPORTED BY WIC - only by freeimage
                    if ("420".Equals(Subsampling)) subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling420;
                    if ("422".Equals(Subsampling)) subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling422;
                    if ("444".Equals(Subsampling)) subsampling = WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling444;

                    if (subsampling != WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsamplingDefault) {
                        var samplingOption = new PROPBAG2[1];
                        samplingOption[0].pstrName = "JpegYCrCbSubsampling";
                        samplingOption[0].vt = VarEnum.VT_UI1;
                        propBag.Write(1, samplingOption, new object[] { (byte)subsampling });
                    }
                }
                //PNG interlace
                if (guidEncoder.Equals(Consts.GUID_ContainerFormatPng)) {
                    var interlaceOption = new PROPBAG2[1];
                    interlaceOption[0].pstrName = "InterlaceOption";

                    propBag.Write(1, interlaceOption, new object[] { Interlace ?? false });

                }

                //Apply the property bag
                outputFrame.Initialize(propBag);

                //Convert the bitmap to the correct pixel format for encoding.

                //Jpeg: encodes as GUID_WICPixelFormat24bppBGR or GUID_WICPixelFormat8bppGray.
                //If the original pixel format has an alpha chanel, we need to specify a matte color.
                //UPDATE - IWICFormatConverter doesn't let you specify a matte color. Disabling code
                if (false && guidEncoder.Equals(Consts.GUID_ContainerFormatJpeg)) {
                    ConversionUtils.HasAlphaAbility(pFormat);
                    var conv = factory.CreateFormatConverter();
                    com.Add(conv);
                    if (conv.CanConvert(pFormat, Consts.GUID_WICPixelFormat24bppBGR)) {
                        /*dither, pIPalette, alphaThresholdPercent, and paletteTranslate are used to mitigate color loss when
                         * converting to a reduced bit-depth format. For conversions that do not need these settings, the
                         * following parameters values should be used: dither set to WICBitmapDitherTypeNone, pIPalette set to NULL,
                         * alphaThresholdPercent set to 0.0f, and paletteTranslate set to WICBitmapPaletteTypeCustom.*/
                        conv.Initialize(data, Consts.GUID_WICPixelFormat24bppBGR, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0f, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                        data = conv;
                        //Oops, we didn't do anything - there's no way to specify a matte color!
                    }
                }

                //GIF encodes as GUID_WICPixelFormat8bppIndexed
                //If the current format is > 8bpp, quantization may be required, and we may need to manually build the palette with Median Cut.

                //PNG encodeds as EVERYTHING! Way too many formats supported.
                // If the user is specifying a colors setting, we need to
                // convert to GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat2bppIndexed, or GUID_WICPixelFormat1bppIndexed

                if ((guidEncoder.Equals(Consts.GUID_ContainerFormatPng) && this.Colors != -1) || (guidEncoder.Equals(Consts.GUID_ContainerFormatGif))) {

                    Guid target = Consts.GUID_WICPixelFormat8bppIndexed;

                    int colors = this.Colors;

                    if (colors > 0 && guidEncoder.Equals(Consts.GUID_ContainerFormatPng)) {
                        if (colors <= 2) target = Consts.GUID_WICPixelFormat1bppIndexed;
                        if (colors <= 4) target = Consts.GUID_WICPixelFormat2bppIndexed;
                        if (colors <= 32) target = Consts.GUID_WICPixelFormat4bppIndexed;
                    }
                    if (colors < 0) colors = 256;
                    if (colors < 2) colors = 2;
                    if (colors > 256) colors = 256;

                    var conv = factory.CreateFormatConverter();
                    com.Add(conv);
                    if (conv.CanConvert(pFormat, target)) {

                        var palette = factory.CreatePalette();
                        com.Add(palette);
                        palette.InitializeFromBitmap(data, (uint)colors, true);

                        /*dither, pIPalette, alphaThresholdPercent, and paletteTranslate are used to mitigate color loss when
                         * converting to a reduced bit-depth format. For conversions that do not need these settings, the
                         * following parameters values should be used: dither set to WICBitmapDitherTypeNone, pIPalette set to NULL,
                         * alphaThresholdPercent set to 0.0f, and paletteTranslate set to WICBitmapPaletteTypeCustom.*/
                        conv.Initialize(data, target, this.Dither ? WICBitmapDitherType.WICBitmapDitherTypeErrorDiffusion :  WICBitmapDitherType.WICBitmapDitherTypeNone,
                                        palette, 50.0f, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                        data = conv;

                    }
                }

                //Get size
                uint fw, fh;
                data.GetSize(out fw, out fh);

                //Set destination frame size
                outputFrame.SetSize(fw,fh);

                // Write the data to the output frame
                outputFrame.WriteSource(data, null);
                outputFrame.Commit();
                encoder.Commit();

            } 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);
                }
            }
        }
Example #25
0
        public static IComObject <IWICBitmap> CreateBitmapFromSourceRect(this IWICImagingFactory factory, IWICBitmapSource source, int x, int y, int width, int height)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

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

            factory.CreateBitmapFromSourceRect(source, x, y, width, height, out var value).ThrowOnError();
            return(new ComObject <IWICBitmap>(value));
        }
Example #26
0
        public static IWICBitmapSource GetOrientedImageSource(this IWICImagingFactory factory, IWICBitmapSource source, WICBitmapTransformOptions opt)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }
            if (opt == WICBitmapTransformOptions.WICBitmapTransformRotate0)
            {
                return(source);
            }
            IWICBitmap iwicbitmap = null;

            factory.CreateBitmapFromSource(source, WICBitmapCreateCacheOption.WICBitmapCacheOnDemand, out iwicbitmap);
            IWICBitmapFlipRotator iwicbitmapFlipRotator = null;

            factory.CreateBitmapFlipRotator(out iwicbitmapFlipRotator);
            iwicbitmapFlipRotator.Initialize(iwicbitmap, opt);
            IWICBitmapSource result = iwicbitmapFlipRotator;

            GraphicsInteropNativeMethods.SafeReleaseComObject(iwicbitmap);
            return(result);
        }
Example #27
0
 public static IWICBitmap CreateBitmapFromSourceRect(this IWICImagingFactory imagingFactory, IWICBitmapSource pIBitmapSource, WICRect rect)
 {
     return(imagingFactory.CreateBitmapFromSourceRect(pIBitmapSource, rect.X, rect.Y, rect.Width, rect.Height));
 }
Example #28
0
        public static IWICBitmapSource ConvertFormat(this IWICImagingFactory factory, IWICBitmapSource source, Guid imageFormat)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }
            IWICFormatConverter iwicformatConverter;

            factory.CreateFormatConverter(out iwicformatConverter);
            iwicformatConverter.Initialize(source, ref imageFormat, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeMedianCut);
            return(iwicformatConverter);
        }
Example #29
0
 public extern IWICBitmap CreateBitmapFromSource([In, MarshalAs(UnmanagedType.Interface)] IWICBitmapSource pIBitmapSource, [In] WICBitmapCreateCacheOption option);
Example #30
0
        public static IWICBitmapSource GetScaledImageSource(this IWICImagingFactory factory, IWICBitmapSource source, float scale)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            int num;
            int num2;

            source.GetSize(out num, out num2);
            IWICBitmapScaler iwicbitmapScaler;

            factory.CreateBitmapScaler(out iwicbitmapScaler);
            iwicbitmapScaler.Initialize(source, (int)((float)num / scale), (int)((float)num2 / scale), WICBitmapInterpolationMode.WICBitmapInterpolationModeFant);
            return(iwicbitmapScaler);
        }
 public WicTransform(WicTransform prev)
 {
     Context = prev.Context;
     Frame   = prev.Frame;
     Source  = prev.Source;
 }
Example #32
0
        protected virtual RequestedAction Encode(IWICComponentFactory factory, IWICBitmapSource data, Size imageSize, ImageJob job)
        {
            WicEncoderPlugin encoder = new WicEncoderPlugin(job.Settings, job.SourcePathData);

            //Create the IStream/MemoryStream
            var outputStream = new MemoryIStream();

            encoder.EncodeToStream(factory, data, imageSize, outputStream);

            object dest = job.Dest;
            // Try to save the bitmap
            if (dest is string) {
                //Make physical and resolve variable references all at the same time.
                job.FinalPath = job.ResolveTemplatedPath(job.Dest as string,
                    delegate(string var) {
                        if ("ext".Equals(var, StringComparison.OrdinalIgnoreCase)) return encoder.Extension;
                        if ("width".Equals(var, StringComparison.OrdinalIgnoreCase)) return imageSize.Width.ToString();
                        if ("height".Equals(var, StringComparison.OrdinalIgnoreCase)) return imageSize.Height.ToString();
                        return null;
                    });
                //If requested, auto-create the parent directory(ies)
                if (job.CreateParentDirectory) {
                    string dirName = Path.GetDirectoryName(job.FinalPath);
                    if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName);
                }

                using (FileStream fs = new FileStream(job.FinalPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) {
                    outputStream.WriteTo(fs);
                }
            } else if (dest is Stream) {
                outputStream.WriteTo((Stream)dest);
            } else return RequestedAction.None;

            return RequestedAction.Cancel;
        }
Example #33
0
 public WicBitmapSource(IWICBitmapSource source, int width, int height)
 {
     this.source = source;
     Width       = width;
     Height      = height;
 }
Example #34
0
 private WicBitmapSource(IWICBitmapSource source, Guid format)
 {
     _source = source;
     Format  = format;
     Stats();
 }
Example #35
0
        public static Bitmap FromWic(IWICBitmapSource source)
        {
            Guid format; //Get the WIC pixel format
            source.GetPixelFormat(out format);
            //Get the matching GDI format
            PixelFormat gdiFormat = ConversionUtils.GetPixelFormat(format);

            //If it's not GDI-supported format, convert it to one.
            IWICComponentFactory factory = null;
            IWICFormatConverter converter = null;
            try {
            if (gdiFormat == PixelFormat.Undefined) {
                factory = (IWICComponentFactory)new WICImagingFactory();
                converter = factory.CreateFormatConverter();
                converter.Initialize(source, Consts.GUID_WICPixelFormat32bppBGRA, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.9f, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                gdiFormat = PixelFormat.Format32bppArgb;
            }
            IWICBitmapSource data = converter != null ? converter : source;

            //Get the dimensions of the WIC bitmap
            uint w, h;
            data.GetSize(out w, out h);

            Bitmap b = new Bitmap((int)w, (int)h, gdiFormat);
            BitmapData bd = b.LockBits(new Rectangle(0, 0, (int)w, (int)h), ImageLockMode.WriteOnly, b.PixelFormat);
            try {
                long result = CopyPixels(data, IntPtr.Zero, (uint)bd.Stride, (uint)(bd.Stride * bd.Height), bd.Scan0);
                if (result == 0x80070057) throw new ArgumentException();
                if (result < 0) throw new Exception("HRESULT " + result);
                return b;
            } finally {
                b.UnlockBits(bd);
            }
            } finally {
            if (converter != null) Marshal.ReleaseComObject(converter);
            if (factory != null) Marshal.ReleaseComObject(factory);
            }
        }
Example #36
0
        /// <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);
                }
            }
        }
Example #37
0
 internal static extern int CopyPixels(IWICBitmapSource bitmap, IntPtr rect, uint cbStride, uint cbBufferSize, IntPtr pvPixels);
 public static void Initialize(this IWICBitmapScaler bitmapScaler, IWICBitmapSource pISource, Size size, WICBitmapInterpolationMode mode)
 {
     bitmapScaler.Initialize(pISource, size.Width, size.Height, mode);
 }
Example #39
0
 public static Resolution GetResolution(this IWICBitmapSource bitmapSource)
 {
     bitmapSource.GetResolution(out double dpiX, out double dpiY);
     return(new Resolution(dpiX, dpiY));
 }
Example #40
0
 protected ImageBase(IWICImagingFactory factory, IWICBitmapSource bitmapSource, Guid wicImageFormat) : this()
 {
     this.LoadFromWic(factory, bitmapSource, wicImageFormat);
 }