Пример #1
0
        private static void EncodeMultiframe(PixelBuffer[] images, int count, WICFlags flags, Guid guidContainerFormat, Stream stream)
        {
            if (images.Length < 2)
            {
                throw new ArgumentException("Cannot encode to multiple frame. Image doesn't have multiple frame");
            }

            using (var encoder = Factory.CreateEncoder(guidContainerFormat))
                using (var propBag = new PropertyBag())
                {
                    using (var eInfo = encoder.EncoderInfo)
                    {
                        if (!eInfo.DoesSupportMultiframe())
                        {
                            throw new NotSupportedException("Cannot encode to multiple frame. Format is not supporting multiple frame");
                        }
                    }

                    encoder.Initialize(stream);

                    for (var i = 0; i < Math.Min(images.Length, count); i++)
                    {
                        var pixelBuffer = images[i];
                        using (var frame = encoder.CreateNewFrame(propBag))
                        {
                            EncodeImage(pixelBuffer, flags, frame);
                        }
                    }

                    encoder.Commit();
                }
        }
Пример #2
0
        //-------------------------------------------------------------------------------------
        // Encodes an image array
        //-------------------------------------------------------------------------------------
        private static void EncodeMultiframe(PixelBuffer[] images, int count, WICFlags flags, Guid guidContainerFormat, Stream stream)
        {
            if (images.Length < 2)
            {
                throw new ArgumentException("Cannot encode to multiple frame. Image doesn't have multiple frame");
            }

            using (var encoder = new WIC.BitmapEncoder(Factory, guidContainerFormat))
            {
                using (var eInfo = encoder.EncoderInfo)
                {
                    if (!eInfo.IsMultiframeSupported)
                    {
                        throw new NotSupportedException("Cannot encode to multiple frame. Format is not supporting multiple frame");
                    }
                }

                encoder.Initialize(stream);

                for (int i = 0; i < Math.Min(images.Length, count); i++)
                {
                    var pixelBuffer = images[i];
                    using (var frame = new WIC.BitmapFrameEncode(encoder))
                        EncodeImage(pixelBuffer, flags, frame);
                }

                encoder.Commit();
            }
        }
Пример #3
0
        //-------------------------------------------------------------------------------------
        // Encodes a single frame
        //-------------------------------------------------------------------------------------
        private static void EncodeImage(PixelBuffer image, WICFlags flags, WIC.BitmapFrameEncode frame)
        {
            Guid pfGuid;

            if (!ToWIC(image.Format, out pfGuid))
            {
                throw new NotSupportedException("Format not supported");
            }

            frame.Initialize();
            frame.SetSize(image.Width, image.Height);
            frame.SetResolution(72, 72);
            Guid targetGuid = pfGuid;

            frame.SetPixelFormat(ref targetGuid);

            if (targetGuid != pfGuid)
            {
                using (var source = new WIC.Bitmap(Factory, image.Width, image.Height, pfGuid, new SDX.DataRectangle(image.DataPointer, image.RowStride), image.BufferStride))
                {
                    using (var converter = new WIC.FormatConverter(Factory))
                    {
                        using (var palette = new WIC.Palette(Factory))
                        {
                            palette.Initialize(source, 256, true);
                            converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, WIC.BitmapPaletteType.Custom);

                            int bpp = GetBitsPerPixel(targetGuid);
                            if (bpp == 0)
                            {
                                throw new NotSupportedException("Unable to determine the Bpp for the target format");
                            }

                            int rowPitch   = (image.Width * bpp + 7) / 8;
                            int slicePitch = rowPitch * image.Height;

                            var temp = SDX.Utilities.AllocateMemory(slicePitch);
                            try
                            {
                                converter.CopyPixels(rowPitch, temp, slicePitch);
                                frame.Palette = palette;
                                frame.WritePixels(image.Height, temp, rowPitch, slicePitch);
                            }
                            finally
                            {
                                SDX.Utilities.FreeMemory(temp);
                            }
                        }
                    }
                }
            }
            else
            {
                // No conversion required
                frame.WritePixels(image.Height, image.DataPointer, image.RowStride, image.BufferStride);
            }

            frame.Commit();
        }
Пример #4
0
 private static void SaveToWICMemory(PixelBuffer[] pixelBuffer, int count, WICFlags flags, ImageFileType fileType, Stream stream)
 {
     if (count > 1)
     {
         EncodeMultiframe(pixelBuffer, count, flags, GetContainerFormatFromFileType(fileType), stream);
     }
     else
     {
         EncodeSingleFrame(pixelBuffer[0], flags, GetContainerFormatFromFileType(fileType), stream);
     }
 }
Пример #5
0
 public _Form(Bitmap img, WICFlags flags)
 {
     _img   = img;
     _flags = flags;
     SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
     AutoScaleMode   = AutoScaleMode.None;
     FormBorderStyle = FormBorderStyle.None; //important
     ShowInTaskbar   = false;                //optional
     TopLevel        = true;                 //optional
     StartPosition   = FormStartPosition.Manual;
     Text            = "Au.AWinImage.CaptureUI";
     Cursor          = _cursor = ACursor.LoadCursorFromMemory(Resources.Resources.red_cross_cursor, 32);
 }
Пример #6
0
        private static WIC.BitmapDitherType GetWICDither(WICFlags flags)
        {
            if ((flags & WICFlags.Dither) != 0)
            {
                return(WIC.BitmapDitherType.Ordered4x4);
            }

            if ((flags & WICFlags.DitherDiffusion) != 0)
            {
                return(WIC.BitmapDitherType.ErrorDiffusion);
            }

            return(WIC.BitmapDitherType.None);
        }
Пример #7
0
        private static WIC.BitmapInterpolationMode GetWICInterp(WICFlags flags)
        {
            if ((flags & WICFlags.FilterPoint) != 0)
            {
                return(WIC.BitmapInterpolationMode.NearestNeighbor);
            }

            if ((flags & WICFlags.FilterLinear) != 0)
            {
                return(WIC.BitmapInterpolationMode.Linear);
            }

            if ((flags & WICFlags.FilterCubic) != 0)
            {
                return(WIC.BitmapInterpolationMode.Cubic);
            }

            return(WIC.BitmapInterpolationMode.Fant);
        }
Пример #8
0
 private static void EncodeSingleFrame(PixelBuffer pixelBuffer, WICFlags flags, Guid guidContainerFormat, Stream stream)
 {
     using (var encoder = new WIC.BitmapEncoder(Factory, guidContainerFormat, stream))
     {
         using (var frame = new WIC.BitmapFrameEncode(encoder))
         {
             if (guidContainerFormat == WIC.ContainerFormatGuids.Bmp)
             {
                 try
                 {
                     frame.Options.Set("EnableV5Header32bppBGRA", true);
                 }
                 catch
                 {
                 }
             }
             EncodeImage(pixelBuffer, flags, frame);
             encoder.Commit();
         }
     }
 }
Пример #9
0
        //-------------------------------------------------------------------------------------
        // Decodes a single frame
        //-------------------------------------------------------------------------------------
        private static Image DecodeSingleFrame(WICFlags flags, ImageDescription metadata, Guid convertGUID, WIC.BitmapFrameDecode frame)
        {
            var image = Image.New(metadata);

            var pixelBuffer = image.PixelBuffer[0];

            if (convertGUID == Guid.Empty)
            {
                frame.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
            }
            else
            {
                using (var converter = new WIC.FormatConverter(Factory))
                {
                    converter.Initialize(frame, convertGUID, GetWICDither(flags), null, 0, WIC.BitmapPaletteType.Custom);
                    converter.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                }
            }

            return(image);
        }
Пример #10
0
        /// <summary>
        /// Determines metadata for image
        /// </summary>
        /// <param name="flags">The flags.</param>
        /// <param name="decoder">The decoder.</param>
        /// <param name="frame">The frame.</param>
        /// <param name="pixelFormat">The pixel format.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">If pixel format is not supported.</exception>
        private static ImageDescription?DecodeMetadata(WICFlags flags, WIC.BitmapDecoder decoder, WIC.BitmapFrameDecode frame, out Guid pixelFormat)
        {
            var size = frame.Size;

            var metadata = new ImageDescription
            {
                Dimension = TextureDimension.Texture2D,
                Width     = size.Width,
                Height    = size.Height,
                Depth     = 1,
                MipLevels = 1,
                ArraySize = (flags & WICFlags.AllFrames) != 0 ? decoder.FrameCount : 1,
                Format    = DetermineFormat(frame.PixelFormat, flags, out pixelFormat)
            };

            if (metadata.Format == DXGI.Format.Unknown)
            {
                return(null);
            }

            return(metadata);
        }
Пример #11
0
        private static void EncodeSingleFrame(PixelBuffer pixelBuffer, WICFlags flags, Guid guidContainerFormat, Stream stream)
        {
            using (var encoder = Factory.CreateEncoder(guidContainerFormat, stream))
                using (var propBag = new PropertyBag())
                {
                    if (guidContainerFormat == ContainerFormatGuids.Bmp)
                    {
                        try
                        {
                            propBag.Set("EnableV5Header32bppBGRA", true);
                        }
                        catch
                        {
                        }
                    }

                    using (var frame = encoder.CreateNewFrame(propBag))
                    {
                        EncodeImage(pixelBuffer, flags, frame);
                        encoder.Commit();
                    }
                }
        }
Пример #12
0
        //-------------------------------------------------------------------------------------
        // Encodes an image array
        //-------------------------------------------------------------------------------------
        private static void EncodeMultiframe( PixelBuffer[] images, int count, WICFlags flags, Guid guidContainerFormat, Stream stream )
        {
            if ( images.Length < 2 )
                throw new ArgumentException("Cannot encode to multiple frame. Image doesn't have multiple frame");

            using (var encoder = new BitmapEncoder(Factory, guidContainerFormat))
            {
                using (var eInfo = encoder.EncoderInfo)
                {
                    if (!eInfo.IsMultiframeSupported)
                        throw new NotSupportedException("Cannot encode to multiple frame. Format is not supporting multiple frame");
                }

                encoder.Initialize(stream);

                for (int i = 0; i < Math.Min(images.Length, count); i++)
                {
                    var pixelBuffer = images[i];
                    using (var frame = new BitmapFrameEncode(encoder))
                        EncodeImage(pixelBuffer, flags, frame);
                }

                encoder.Commit();
            }
        }
Пример #13
0
        //-------------------------------------------------------------------------------------
        // Returns the DXGI format and optionally the WIC pixel Guid to convert to
        //-------------------------------------------------------------------------------------
        private static DXGI.Format DetermineFormat(Guid pixelFormat, WICFlags flags, out Guid pixelFormatOut)
        {
            DXGI.Format format = ToDXGI(pixelFormat);
            pixelFormatOut = Guid.Empty;

            if (format == DXGI.Format.Unknown)
            {
                for (int i = 0; i < WICConvertTable.Length; ++i)
                {
                    if (WICConvertTable[i].source == pixelFormat)
                    {
                        pixelFormatOut = WICConvertTable[i].target;

                        format = ToDXGI(WICConvertTable[i].target);
                        Debug.Assert(format != DXGI.Format.Unknown);
                        break;
                    }
                }
            }

            // Handle special cases based on flags
            switch (format)
            {
                case DXGI.Format.B8G8R8A8_UNorm: // BGRA
                case DXGI.Format.B8G8R8X8_UNorm: // BGRX
                    if ((flags & WICFlags.ForceRgb) != 0)
                    {
                        format = DXGI.Format.R8G8B8A8_UNorm;
                        pixelFormatOut = WIC.PixelFormat.Format32bppRGBA;
                    }
                    break;

                case DXGI.Format.R10G10B10_Xr_Bias_A2_UNorm:
                    if ((flags & WICFlags.NoX2Bias) != 0)
                    {
                        format = DXGI.Format.R10G10B10A2_UNorm;
                        pixelFormatOut = WIC.PixelFormat.Format32bppRGBA1010102;
                    }
                    break;

                case DXGI.Format.B5G5R5A1_UNorm:
                case DXGI.Format.B5G6R5_UNorm:
                    if ((flags & WICFlags.No16Bpp) != 0)
                    {
                        format = DXGI.Format.R8G8B8A8_UNorm;
                        pixelFormatOut = WIC.PixelFormat.Format32bppRGBA;
                    }
                    break;

                case DXGI.Format.R1_UNorm:
                    if ((flags & WICFlags.FlagsAllowMono) == 0)
                    {
                        // By default we want to promote a black & white to greyscale since R1 is not a generally supported D3D format
                        format = DXGI.Format.R8_UNorm;
                        pixelFormatOut = WIC.PixelFormat.Format8bppGray;
                    }
                    break;
            }

            return format;
        }
Пример #14
0
        //-------------------------------------------------------------------------------------
        // Decodes an image array, resizing/format converting as needed
        //-------------------------------------------------------------------------------------
        private static Image DecodeMultiframe(WICFlags flags, ImageDescription metadata, WIC.BitmapDecoder decoder)
        {
            var image = Image.New(metadata);

            Guid sourceGuid;

            if (!ToWIC(metadata.Format, out sourceGuid))
            {
                return(null);
            }

            for (int index = 0; index < metadata.ArraySize; ++index)
            {
                var pixelBuffer = image.PixelBuffer[index, 0];

                using (var frame = decoder.GetFrame(index))
                {
                    var pfGuid = frame.PixelFormat;
                    var size   = frame.Size;

                    if (pfGuid == sourceGuid)
                    {
                        if (size.Width == metadata.Width && size.Height == metadata.Height)
                        {
                            // This frame does not need resized or format converted, just copy...
                            frame.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                        }
                        else
                        {
                            // This frame needs resizing, but not format converted
                            using (var scaler = new WIC.BitmapScaler(Factory))
                            {
                                scaler.Initialize(frame, metadata.Width, metadata.Height, GetWICInterp(flags));
                                scaler.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                            }
                        }
                    }
                    else
                    {
                        // This frame required format conversion
                        using (var converter = new WIC.FormatConverter(Factory))
                        {
                            converter.Initialize(frame, pfGuid, GetWICDither(flags), null, 0, WIC.BitmapPaletteType.Custom);

                            if (size.Width == metadata.Width && size.Height == metadata.Height)
                            {
                                converter.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                            }
                            else
                            {
                                // This frame needs resizing, but not format converted
                                using (var scaler = new WIC.BitmapScaler(Factory))
                                {
                                    scaler.Initialize(frame, metadata.Width, metadata.Height, GetWICInterp(flags));
                                    scaler.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                                }
                            }
                        }
                    }
                }
            }
            return(image);
        }
Пример #15
0
        /// <summary>
        /// Determines metadata for image
        /// </summary>
        /// <param name="flags">The flags.</param>
        /// <param name="decoder">The decoder.</param>
        /// <param name="frame">The frame.</param>
        /// <param name="pixelFormat">The pixel format.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">If pixel format is not supported.</exception>
        private static ImageDescription? DecodeMetadata(WICFlags flags, BitmapDecoder decoder, BitmapFrameDecode frame, out Guid pixelFormat)
        {
            var size = frame.Size;

            var metadata = new ImageDescription
                               {
                                   Dimension = TextureDimension.Texture2D,
                                   Width = size.Width,
                                   Height = size.Height,
                                   Depth = 1,
                                   MipLevels = 1,
                                   ArraySize = (flags & WICFlags.AllFrames) != 0 ? decoder.FrameCount : 1,
                                   Format = DetermineFormat(frame.PixelFormat, flags, out pixelFormat)
                               };

            if (metadata.Format == DXGI.Format.Unknown)
                return null;

            return metadata;
        }
Пример #16
0
        private static BitmapDitherType GetWICDither(WICFlags flags)
        {
            if ((flags & WICFlags.Dither) != 0)
                return BitmapDitherType.Ordered4x4;

            if ((flags & WICFlags.DitherDiffusion) != 0)
                return BitmapDitherType.ErrorDiffusion;

            return BitmapDitherType.None;
        }
Пример #17
0
        //-------------------------------------------------------------------------------------
        // Returns the DXGI format and optionally the WIC pixel Guid to convert to
        //-------------------------------------------------------------------------------------
        private static DXGI.Format DetermineFormat(Guid pixelFormat, WICFlags flags, out Guid pixelFormatOut)
        {
            DXGI.Format format = ToDXGI(pixelFormat);
            pixelFormatOut = Guid.Empty;

            if (format == DXGI.Format.Unknown)
            {
                for (int i = 0; i < WICConvertTable.Length; ++i)
                {
                    if (WICConvertTable[i].source == pixelFormat)
                    {
                        pixelFormatOut = WICConvertTable[i].target;

                        format = ToDXGI(WICConvertTable[i].target);
                        Debug.Assert(format != DXGI.Format.Unknown);
                        break;
                    }
                }
            }

            // Handle special cases based on flags
            switch (format)
            {
            case DXGI.Format.B8G8R8A8_UNorm:     // BGRA
            case DXGI.Format.B8G8R8X8_UNorm:     // BGRX
                if ((flags & WICFlags.ForceRgb) != 0)
                {
                    format         = DXGI.Format.R8G8B8A8_UNorm;
                    pixelFormatOut = WIC.PixelFormat.Format32bppRGBA;
                }
                break;

            case DXGI.Format.R10G10B10_Xr_Bias_A2_UNorm:
                if ((flags & WICFlags.NoX2Bias) != 0)
                {
                    format         = DXGI.Format.R10G10B10A2_UNorm;
                    pixelFormatOut = WIC.PixelFormat.Format32bppRGBA1010102;
                }
                break;

            case DXGI.Format.B5G5R5A1_UNorm:
            case DXGI.Format.B5G6R5_UNorm:
                if ((flags & WICFlags.No16Bpp) != 0)
                {
                    format         = DXGI.Format.R8G8B8A8_UNorm;
                    pixelFormatOut = WIC.PixelFormat.Format32bppRGBA;
                }
                break;

            case DXGI.Format.R1_UNorm:
                if ((flags & WICFlags.FlagsAllowMono) == 0)
                {
                    // By default we want to promote a black & white to greyscale since R1 is not a generally supported D3D format
                    format         = DXGI.Format.R8_UNorm;
                    pixelFormatOut = WIC.PixelFormat.Format8bppGray;
                }
                break;
            }

            return(format);
        }
Пример #18
0
        private static BitmapInterpolationMode GetWICInterp(WICFlags flags)
        {
            if ((flags & WICFlags.FilterPoint) != 0)
                return BitmapInterpolationMode.NearestNeighbor;

            if ((flags & WICFlags.FilterLinear) != 0)
                return BitmapInterpolationMode.Linear;

            if ((flags & WICFlags.FilterCubic) != 0)
                return BitmapInterpolationMode.Cubic;

            return BitmapInterpolationMode.Fant;
        }
Пример #19
0
        /// <summary>
        /// Creates image from a user-selected area of screen pixels. Or gets single pixel color, or just rectangle.
        /// Returns false if cancelled.
        /// </summary>
        /// <param name="result">Receives results.</param>
        /// <param name="flags"></param>
        /// <param name="toolWindow">Owner window. Temporarily hides it and its owner windows.</param>
        /// <remarks>
        /// Gets all screen pixels and shows in a full-screen topmost window, where the user can select an area.
        /// </remarks>
        public static bool CaptureUI(out WICResult result, WICFlags flags = 0, AnyWnd toolWindow = default)
        {
            result = default;

            switch (flags & (WICFlags.Image | WICFlags.Color | WICFlags.Rectangle))
            {
            case 0:
            case WICFlags.Image:
            case WICFlags.Color:
            case WICFlags.Rectangle: break;

            default: throw new ArgumentException();
            }

            AWnd[] aw = null; AWnd wTool = default;
            try {
                if (!toolWindow.IsEmpty)
                {
                    wTool = toolWindow.Wnd;
                    aw    = wTool.Get.OwnersAndThis(true);
                    foreach (var w in aw)
                    {
                        w.ShowLL(false);
                    }
                    using (new AInputBlocker(BIEvents.MouseClicks)) ATime.SleepDoEvents(300);                    //time for animations
                }

g1:
                RECT rs = SystemInformation.VirtualScreen;
                //RECT rs = AScreen.Primary.Bounds; //for testing, to see Write output in other screen
                Bitmap bs;
                bool   windowPixels = flags.HasAny(WICFlags.WindowDC | WICFlags.PrintWindow);
                if (windowPixels)
                {
                    if (!_WaitForHotkey("Press F3 to select window from mouse pointer."))
                    {
                        return(false);
                    }
                    var w = AWnd.FromMouse(WXYFlags.NeedWindow);
                    w.GetClientRect(out var rc, inScreen: true);
                    using var bw = Capture(w, w.ClientRect, flags.Has(WICFlags.PrintWindow));
                    bs           = new Bitmap(rs.Width, rs.Height);
                    using var g  = Graphics.FromImage(bs);
                    g.Clear(Color.Black);
                    g.DrawImage(bw, rc.left, rc.top);
                }
                else
                {
                    bs = Capture(rs);
                }

                var f = new _Form(bs, flags);
                f.Bounds = rs;
                switch (f.ShowDialog())
                {
                case DialogResult.OK: break;

                case DialogResult.Retry:
                    if (!windowPixels && !_WaitForHotkey("Press F3 when ready for new screenshot."))
                    {
                        return(false);
                    }
                    goto g1;

                default: return(false);
                }

                var r = f.Result;
                r.wnd  = _WindowFromRect(r);
                result = r;
            }
            finally {
                if (aw != null)
                {
                    foreach (var w in aw)
                    {
                        w.ShowLL(true);
                    }
                    if (wTool.IsAlive)
                    {
                        wTool.ShowNotMinimized();
                        wTool.ActivateLL();
                    }
                }
            }
            return(true);
        }
Пример #20
0
        //-------------------------------------------------------------------------------------
        // Decodes a single frame
        //-------------------------------------------------------------------------------------
        private static Image DecodeSingleFrame(WICFlags flags, ImageDescription metadata, Guid convertGUID, BitmapFrameDecode frame)
        {
            var image = Image.New(metadata);

            var pixelBuffer = image.PixelBuffer[0];

            if (convertGUID == Guid.Empty)
            {
                frame.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
            }
            else
            {
                using (var converter = new FormatConverter(Factory))
                {
                    converter.Initialize(frame, convertGUID, GetWICDither(flags), null, 0, BitmapPaletteType.Custom);
                    converter.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                }
            }

            return image;
        }
Пример #21
0
 private static void EncodeSingleFrame( PixelBuffer pixelBuffer, WICFlags flags, Guid guidContainerFormat, Stream stream )
 {
     using (var encoder = new BitmapEncoder(Factory, guidContainerFormat, stream))
     {
         using (var frame = new BitmapFrameEncode(encoder))
         {
             if (guidContainerFormat == ContainerFormatGuids.Bmp)
             {
                 try
                 {
                     frame.Options.Set("EnableV5Header32bppBGRA", true);
                 }
                 catch
                 {
                 }
             }
             EncodeImage(pixelBuffer, flags, frame);
             encoder.Commit();
         }
     }
 }
Пример #22
0
        //-------------------------------------------------------------------------------------
        // Encodes a single frame
        //-------------------------------------------------------------------------------------
        private static void EncodeImage( PixelBuffer image, WICFlags flags, BitmapFrameEncode frame)
        {
            Guid pfGuid;
            if (! ToWIC(image.Format, out pfGuid))
                throw new NotSupportedException("Format not supported");

            frame.Initialize();
            frame.SetSize(image.Width, image.Height);
            frame.SetResolution(72, 72);
            Guid targetGuid = pfGuid;
            frame.SetPixelFormat(ref targetGuid);

            if (targetGuid != pfGuid)
            {
                using (var source = new Bitmap(Factory, image.Width, image.Height, pfGuid, new DataRectangle(image.DataPointer, image.RowStride), image.BufferStride))
                {
                    using (var converter = new FormatConverter(Factory))
                    {
                        using (var palette = new Palette(Factory))
                        {
                            palette.Initialize(source, 256, true);
                            converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, BitmapPaletteType.Custom);

                            int bpp = GetBitsPerPixel(targetGuid);
                            if (bpp == 0) throw new NotSupportedException("Unable to determine the Bpp for the target format");

                            int rowPitch = (image.Width * bpp + 7) / 8;
                            int slicePitch = rowPitch * image.Height;

                            var temp = Utilities.AllocateMemory(slicePitch);
                            try
                            {
                                converter.CopyPixels(rowPitch, temp, slicePitch);
                                frame.Palette = palette;
                                frame.WritePixels(image.Height, temp, rowPitch, slicePitch);
                            }
                            finally
                            {
                                Utilities.FreeMemory(temp);
                            }
                        }
                    }
                }
            }
            else
            {
                // No conversion required
                frame.WritePixels(image.Height, image.DataPointer, image.RowStride, image.BufferStride);
            }

            frame.Commit();
        }
Пример #23
0
        //-------------------------------------------------------------------------------------
        // Decodes an image array, resizing/format converting as needed
        //-------------------------------------------------------------------------------------
        private static Image DecodeMultiframe(WICFlags flags, ImageDescription metadata, BitmapDecoder decoder)
        {
            var image = Image.New(metadata);

            Guid sourceGuid;
            if (!ToWIC(metadata.Format, out sourceGuid))
                return null;

            for (int index = 0; index < metadata.ArraySize; ++index)
            {
                var pixelBuffer = image.PixelBuffer[index, 0];

                using (var frame = decoder.GetFrame(index))
                {
                    var pfGuid = frame.PixelFormat;
                    var size = frame.Size;

                    if (pfGuid == sourceGuid)
                    {
                        if (size.Width == metadata.Width && size.Height == metadata.Height)
                        {
                            // This frame does not need resized or format converted, just copy...
                            frame.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                        }
                        else
                        {
                            // This frame needs resizing, but not format converted
                            using (var scaler = new BitmapScaler(Factory))
                            {
                                scaler.Initialize(frame, metadata.Width, metadata.Height, GetWICInterp(flags));
                                scaler.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                            }
                        }
                    }
                    else
                    {
                        // This frame required format conversion
                        using (var converter = new FormatConverter(Factory))
                        {
                            converter.Initialize(frame, pfGuid, GetWICDither(flags), null, 0, BitmapPaletteType.Custom);

                            if (size.Width == metadata.Width && size.Height == metadata.Height)
                            {
                                converter.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                            }
                            else
                            {
                                // This frame needs resizing, but not format converted
                                using (var scaler = new BitmapScaler(Factory))
                                {
                                    scaler.Initialize(frame, metadata.Width, metadata.Height, GetWICInterp(flags));
                                    scaler.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride);
                                }
                            }
                        }
                    }
                }
            }
            return image;
        }
Пример #24
0
 private static void SaveToWICMemory(PixelBuffer[] pixelBuffer, int count, WICFlags flags, ImageFileType fileType, Stream stream)
 {
     if (count > 1)
         EncodeMultiframe(pixelBuffer, count, flags, GetContainerFormatFromFileType(fileType), stream);
     else
         EncodeSingleFrame(pixelBuffer[0], flags, GetContainerFormatFromFileType(fileType), stream);
 }
Пример #25
0
        /// <summary>
        /// Function to find the best buffer format for a given pixel format.
        /// </summary>
        /// <param name="sourcePixelFormat">Pixel format to translate.</param>
        /// <param name="flags">Flags to apply to the pixel format conversion.</param>
        /// <param name="updatedPixelFormat">The updated pixel format after flags are applied.</param>
        /// <returns>The buffer format, or Unknown if the format couldn't be converted.</returns>
        public BufferFormat FindBestFormat(Guid sourcePixelFormat, WICFlags flags, out Guid updatedPixelFormat)
        {
            BufferFormat result = GetGorgonFormat(sourcePixelFormat);

            updatedPixelFormat = Guid.Empty;

            if (result == BufferFormat.Unknown)
            {
                if (sourcePixelFormat == WIC.PixelFormat.Format96bppRGBFixedPoint)
                {
                    updatedPixelFormat = WIC.PixelFormat.Format128bppRGBAFloat;
                    result             = BufferFormat.R32G32B32A32_Float;
                }
                else
                {
                    // Find the best fit format if we couldn't find an exact match.
                    for (int i = 0; i < _wicBestFitFormat.Length; i++)
                    {
                        if (_wicBestFitFormat[i].Source != sourcePixelFormat)
                        {
                            continue;
                        }

                        updatedPixelFormat = _wicBestFitFormat[i].Destination;
                        result             = GetGorgonFormat(updatedPixelFormat);

                        // We couldn't find the format, bail out.
                        if (result == BufferFormat.Unknown)
                        {
                            return(result);
                        }
                        break;
                    }
                }
            }

            switch (result)
            {
            case BufferFormat.B8G8R8A8_UIntNormal:
            case BufferFormat.B8G8R8X8_UIntNormal:
                if ((flags & WICFlags.ForceRGB) == WICFlags.ForceRGB)
                {
                    result             = BufferFormat.R8G8B8A8_UIntNormal;
                    updatedPixelFormat = WIC.PixelFormat.Format32bppRGBA;
                }
                break;

            case BufferFormat.R10G10B10_XR_BIAS_A2_UIntNormal:
                if ((flags & WICFlags.NoX2Bias) == WICFlags.NoX2Bias)
                {
                    result             = BufferFormat.R10G10B10A2_UIntNormal;
                    updatedPixelFormat = WIC.PixelFormat.Format32bppRGBA1010102;
                }
                break;

            case BufferFormat.B5G5R5A1_UIntNormal:
            case BufferFormat.B5G6R5_UIntNormal:
                if ((flags & WICFlags.No16BPP) == WICFlags.No16BPP)
                {
                    result             = BufferFormat.R8G8B8A8_UIntNormal;
                    updatedPixelFormat = WIC.PixelFormat.Format32bppRGBA;
                }
                break;

            case BufferFormat.R1_UIntNormal:
                if ((flags & WICFlags.AllowMono) != WICFlags.AllowMono)
                {
                    result             = BufferFormat.R1_UIntNormal;
                    updatedPixelFormat = WIC.PixelFormat.Format8bppGray;
                }
                break;
            }

            return(result);
        }