/// <summary>
        /// Retrieves the metadata block or item identified by a metadata query expression.
        /// </summary>
        /// <param name="name">The query expression to the requested metadata block or item.</param>
        /// <param name="value">The metadata block or item requested or null if not found.</param>
        /// <returns>True when the metadata block or item was found, otherwise false.</returns>
        /// <remarks>
        /// GetMetadataByName uses metadata query expressions to access embedded metadata. For more information on the metadata query language, see the Metadata Query Language Overview.
        /// <br/>
        /// If multiple blocks or items exist that are expressed by the same query expression, the first metadata block or item found will be returned.
        /// </remarks>
        public static bool TryGetMetadataByName(this IWICMetadataQueryReader metadataQueryReader, string name, out object?value)
        {
            if (metadataQueryReader is null)
            {
                throw new NullReferenceException();
            }
            if (name is null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            var variant = new PROPVARIANT();

            try
            {
                metadataQueryReader.GetMetadataByName(name, ref variant);
                value = PropVariantHelper.Decode(variant);
                return(true);
            }
            catch (COMException ex) when(ex.ErrorCode == WinCodecError.PROPERTY_NOT_FOUND)
            {
                value = null;
                return(false);
            }
            finally
            {
                PropVariantHelper.Free(variant);
            }
        }
Exemple #2
0
        private void GetBackgroundColor(IWICMetadataQueryReader wicMetadataQueryReader)
        {
            // 如果图片里面包含了 global palette 就需要获取 palette 和背景色
            var propertyVariant = new PROPVARIANT();

            wicMetadataQueryReader.GetMetadataByName("/logscrdesc/GlobalColorTableFlag", ref propertyVariant);

            byte backgroundIndex = 0;

            var globalPalette = (propertyVariant.Type & VARTYPE.VT_BOOL) == VARTYPE.VT_BOOL &&
                                propertyVariant.Value.UI1 > 0;

            if (globalPalette)
            {
                propertyVariant = new PROPVARIANT();
                wicMetadataQueryReader.GetMetadataByName("/logscrdesc/BackgroundColorIndex", ref propertyVariant);

                if ((propertyVariant.Type & VARTYPE.VT_UI1) == VARTYPE.VT_UI1)
                {
                    backgroundIndex = propertyVariant.Value.UI1;
                }

                var wicPalette = WicImagingFactory.CreatePalette();
                WicBitmapDecoder.CopyPalette(wicPalette);
            }
        }
        public static bool TryGetMetadataByName(this IWICMetadataQueryReader meta, string name, out PropVariant val)
        {
            val = null;

            int hr = ProxyFunctions.GetMetadataByName(meta, name, IntPtr.Zero);

            if (hr >= 0)
            {
                val = new PropVariant();
                meta.GetMetadataByName(name, val);
            }
            return(hr >= 0);
        }
Exemple #4
0
        public ImageSource(byte[] buffer)
        {
            if (buffer == null || buffer.Length == 0)
            {
                throw new ArgumentException("Image buffer does not contain a valid image to load.", "buffer");
            }
            this.buffer = buffer;
            IWICImagingFactory    iwicimagingFactory    = WicUtility.CreateFactory();
            IWICBitmapFrameDecode iwicbitmapFrameDecode = iwicimagingFactory.Load(this.ImageStream);
            int num;
            int num2;

            iwicbitmapFrameDecode.GetSize(out num, out num2);
            this.Width  = (float)num;
            this.Height = (float)num2;
            IWICMetadataQueryReader iwicmetadataQueryReader = null;

            try
            {
                iwicbitmapFrameDecode.GetMetadataQueryReader(out iwicmetadataQueryReader);
                string   s;
                DateTime value;
                if (iwicmetadataQueryReader.TryGetMetadataProperty("/app1/ifd/exif/subifd:{uint=36867}", out s) && DateTime.TryParseExact(s, "yyyy:MM:dd HH:mm:ss", null, DateTimeStyles.None, out value))
                {
                    this.DateTaken = new DateTime?(value);
                }
            }
            catch (Exception)
            {
            }
            try
            {
                ushort value2;
                if (iwicmetadataQueryReader.TryGetMetadataProperty("/app1/ifd/{ushort=274}", out value2))
                {
                    this.Orientation = ImageSource.TransformOptionsFromUshort(value2);
                }
                else
                {
                    this.Orientation = WICBitmapTransformOptions.WICBitmapTransformRotate0;
                }
            }
            catch (Exception)
            {
            }
            GraphicsInteropNativeMethods.SafeReleaseComObject(iwicmetadataQueryReader);
            GraphicsInteropNativeMethods.SafeReleaseComObject(iwicbitmapFrameDecode);
            GraphicsInteropNativeMethods.SafeReleaseComObject(iwicimagingFactory);
        }
Exemple #5
0
 public static IEnumerable <string> GetNamesRecursive(this IWICMetadataQueryReader reader)
 {
     foreach (var name in reader.GetNames())
     {
         var val = reader.GetMetadataByName(name);
         if (val is IWICMetadataQueryReader)
         {
             foreach (var childName in GetNamesRecursive((IWICMetadataQueryReader)val))
             {
                 yield return(name + childName);
             }
         }
         else
         {
             yield return(name);
         }
     }
 }
        public static bool TryGetMetadataByName(this IWICMetadataQueryReader meta, string name, [NotNullWhen(true)] out PropVariant?value)
        {
            value = null;

            int hr = ProxyFunctions.GetMetadataByName(meta, name, IntPtr.Zero);

            if (hr >= 0)
            {
                value = new PropVariant();

                var pvMarshal = PropVariant.Marshaler.GetInstance(null);
                var pvNative  = pvMarshal.MarshalManagedToNative(value);
                hr = ProxyFunctions.GetMetadataByName(meta, name, pvNative);
                pvMarshal.MarshalNativeToManaged(pvNative);
                pvMarshal.CleanUpNativeData(pvNative);
            }

            return(hr >= 0);
        }
        public static bool TryGetMetadataByName <T>(this IWICMetadataQueryReader metadataQueryReader, string name, out T value)
        {
            var variant = new PROPVARIANT();

            try
            {
                metadataQueryReader.GetMetadataByName(name, ref variant);
                return(TryDecode(ref variant, out value));
            }
            catch (COMException ex) when(ex.ErrorCode == HResult.WINCODEC_ERR_PROPERTYNOTFOUND)
            {
                value = default(T);
                return(false);
            }
            finally
            {
                Dispose(ref variant);
            }
        }
Exemple #8
0
        public static bool TryGetMetadataProperty <T>(this IWICMetadataQueryReader queryReader, string propertyPath, out T value)
        {
            if (queryReader == null)
            {
                throw new ArgumentNullException("queryReader");
            }
            value = default(T);
            PROPVARIANT propvariant    = default(PROPVARIANT);
            int         metadataByName = queryReader.GetMetadataByName(propertyPath, out propvariant);

            if (-2003292352 != metadataByName)
            {
                GraphicsInteropNativeMethods.CheckNativeResult(metadataByName);
                value = (T)((object)propvariant.Value);
                propvariant.Dispose();
                return(true);
            }
            propvariant.Dispose();
            return(false);
        }
        /// <summary>
        /// Retrieves the metadata block or item identified by a metadata query expression.
        /// </summary>
        /// <param name="name">The query expression to the requested metadata block or item.</param>
        /// <returns>The metadata block or item requested.</returns>
        /// <exception cref="COMException">Thrown when the metadata block or item was not found (HRESULT 0x88982F40).</exception>
        /// <remarks>
        /// GetMetadataByName uses metadata query expressions to access embedded metadata. For more information on the metadata query language, see the Metadata Query Language Overview.
        /// <br/>
        /// If multiple blocks or items exist that are expressed by the same query expression, the first metadata block or item found will be returned.
        /// </remarks>
        public static object GetMetadataByName(this IWICMetadataQueryReader metadataQueryReader, string name)
        {
            if (metadataQueryReader is null)
            {
                throw new NullReferenceException();
            }
            if (name is null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            var variant = new PROPVARIANT();

            try
            {
                metadataQueryReader.GetMetadataByName(name, ref variant);
                return(PropVariantHelper.Decode(variant));
            }
            finally
            {
                PropVariantHelper.Free(variant);
            }
        }
Exemple #10
0
 public void GetMetadataQueryReader(out IWICMetadataQueryReader ppIMetadataQueryReader)
 {
     Log.Trace("GetMetadataQueryReader called");
     ppIMetadataQueryReader = new MetadataEnumerator(exif);
     Log.Trace("GetMetadataQueryReader finished");
 }
Exemple #11
0
 public extern IWICMetadataQueryWriter CreateQueryWriterFromReader([In, MarshalAs(UnmanagedType.Interface)] IWICMetadataQueryReader pIQueryReader, [In] ref Guid pguidVendor);
        public static string GetLocation(this IWICMetadataQueryReader metadataQueryReader)
        {
            FetchIntoBuffer <char> fetcher = metadataQueryReader.GetLocation;

            return(fetcher.FetchString());
        }
        public static bool TryGetMetadataQueryReader(this IWICBitmapFrameDecode frame, out IWICMetadataQueryReader rdr)
        {
            int hr = ProxyFunctions.GetMetadataQueryReader(frame, out rdr);

            return(hr >= 0);
        }
        public static bool HasMetadataName(this IWICMetadataQueryReader meta, string name)
        {
            int hr = GetMetadataByName(meta, name, IntPtr.Zero);

            return(hr >= 0);
        }
 private extern static int GetMetadataByName(IWICMetadataQueryReader THIS_PTR, [MarshalAs(UnmanagedType.LPWStr)] string wzName, IntPtr pvarValue);
Exemple #16
0
 public static IWICMetadataQueryWriter CreateQueryWriterFromReader(this IWICImagingFactory imagingFactory, IWICMetadataQueryReader pIQueryReader, Guid?pguidVendor = null)
 {
     using (var pguidVendorPtr = CoTaskMemPtr.From(pguidVendor))
     {
         return(imagingFactory.CreateQueryWriterFromReader(pIQueryReader, pguidVendorPtr));
     }
 }
        unsafe public static void UpdateGifAnimationContext(WicGifContainer cont, IWICBitmapSource src, IWICMetadataQueryReader meta)
        {
            Debug.Assert(cont.AnimationContext != null);
            var anictx = cont.AnimationContext;

            const int bytesPerPixel = 4;

            var finfo = GetGifFrameInfo(cont, src, meta);
            var fbuff = anictx.FrameBufferSource ??= new FrameBufferSource(cont.ScreenWidth, cont.ScreenHeight, PixelFormat.Bgra32Bpp);
            var bspan = fbuff.Span;

            fbuff.ResumeTiming();

            // Most GIF viewers clear the background to transparent instead of the background color when the next frame has transparency
            bool ftrans = meta.GetValueOrDefault <bool>(Wic.Metadata.Gif.TransparencyFlag);

            if (!finfo.FullScreen && anictx.LastDisposal == GifDisposalMethod.RestoreBackground)
            {
                MemoryMarshal.Cast <byte, uint>(bspan).Fill(ftrans ? 0 : cont.BackgroundColor);
            }

            // Similarly, they overwrite a background color with transparent pixels but overlay instead when the previous frame is preserved
            var fspan = bspan.Slice(finfo.Top * fbuff.Stride + finfo.Left * bytesPerPixel);

            fixed(byte *buff = fspan)
            {
                if (!ftrans || anictx.LastDisposal == GifDisposalMethod.RestoreBackground)
                {
                    src.CopyPixels(WICRect.Null, (uint)fbuff.Stride, (uint)fspan.Length, (IntPtr)buff);
                }
                else
                {
                    using var overlay = new OverlayTransform(fbuff, src.AsPixelSource(nameof(IWICBitmapFrameDecode)), finfo.Left, finfo.Top, true, true);
                    overlay.CopyPixels(new PixelArea(finfo.Left, finfo.Top, finfo.Width, finfo.Height), fbuff.Stride, fspan.Length, (IntPtr)buff);
                }
            }

            fbuff.PauseTiming();
        }
 /// <summary>
 /// Retrieves the current path relative to the root metadata block.
 /// </summary>
 /// <returns>The current namespace location.</returns>
 /// <remarks>
 /// If the query reader is relative to the top of the metadata hierarchy, it will return a single-char string.
 /// <br/>
 /// If the query reader is relative to a nested metadata block, this method will return the path to the current query reader.
 /// </remarks>
 public static string GetLocation(this IWICMetadataQueryReader metadataQueryReader)
 {
     return(FetchIntoBufferHelper.FetchString(metadataQueryReader.GetLocation));
 }
 /// <summary>
 /// Gets the names of all metadata items at the current relative location within the metadata hierarchy.
 /// </summary>
 /// <returns>An enumerable that contains query strings that can be used in the current <see cref="IWICMetadataQueryReader"/>.</returns>
 /// <remarks>
 /// The retrieved enumerable only contains query strings for the metadata blocks and items in the current level of the hierarchy.
 /// </remarks>
 public static IEnumerable <string> GetNames(this IWICMetadataQueryReader metadataQueryReader)
 {
     return(metadataQueryReader.GetEnumerator().AsEnumerable());
 }
 private extern static int GetMetadataQueryReader(IWICBitmapFrameDecode THIS_PTR, out IWICMetadataQueryReader ppIMetadataQueryReader);
 public void GetMetadataQueryReader(out IWICMetadataQueryReader ppIMetadataQueryReader)
 {
     Log.Trace("GetMetadataQueryReader called");
     ppIMetadataQueryReader = new MetadataEnumerator(exif);
     Log.Trace("GetMetadataQueryReader finished");
 }
        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);
        }