Пример #1
0
        private void GetWebpInfo(IntPtr ptrRawWebP, int webpDataSize, out int width, out int height, out bool has_alpha, out bool has_animation, out string format)
        {
            VP8StatusCode         result;
            WebPBitstreamFeatures features = new WebPBitstreamFeatures();

            result = WebPWrapper.WebPGetFeatures(ptrRawWebP, webpDataSize, ref features);
            if (result == 0)
            {
                width         = features.Width;
                height        = features.Height;
                has_alpha     = (features.Has_alpha == 1);
                has_animation = (features.Has_animation == 1);
                switch (features.Format)
                {
                case 1:
                    format = "lossy";
                    break;

                case 2:
                    format = "lossless";
                    break;

                default:
                    format = "undefined";
                    break;
                }
            }
            else
            {
                throw new Exception(result.ToString());
            }
        }
Пример #2
0
        private void decodeWebP(MemoryStream stream)
        {
            Bitmap     bmp         = null;
            Bitmap     firstbmp    = null;
            bool       firstbitmap = true;
            BitmapData bmpData     = null;
            IntPtr     dec         = (IntPtr)0;
            const int  UintBytes   = 4;

            byte []  rawWebP    = stream.ToArray();
            UIntPtr  dataSize   = (UIntPtr)rawWebP.Length;
            GCHandle pinnedWebP = GCHandle.Alloc(rawWebP, GCHandleType.Pinned);
            IntPtr   ptrData    = pinnedWebP.AddrOfPinnedObject();

            try
            {
                //Get info about webp image
                GetWebpInfo(ptrData, rawWebP.Length, out int imgWidth, out int imgHeight, out bool hasAlpha, out bool hasAnimation, out string format);

                if (hasAnimation)
                {
                    //demux the image
                    WebPData webpdata = new WebPData()
                    {
                        bytes = ptrData, size = dataSize
                    };
                    WebPAnimDecoderOptions dec_options = new WebPAnimDecoderOptions();
                    //init decoder options with default values
                    WebPWrapper.WebPAnimDecoderOptionsInit(ref dec_options);
                    //set color mode to blue green red alpha to match up with how the bitmap is formatted
                    dec_options.color_mode = WEBP_CSP_MODE.MODE_BGRA;
                    //create the decoder
                    dec = WebPWrapper.WebPAnimDecoderNew(ref webpdata, ref dec_options);
                    IntPtr       buf;
                    int          timestamp;
                    uint         outputSize;
                    WebPAnimInfo animinfo = new WebPAnimInfo();
                    //get animation info
                    WebPWrapper.WebPAnimDecoderGetInfo(dec, ref animinfo);
                    imgWidth  = (int)animinfo.canvas_width;
                    imgHeight = (int)animinfo.canvas_height;
                    int  prevtimestamp = 0;
                    bool first         = true;
                    while (WebPWrapper.WebPAnimDecoderHasMoreFrames(dec) == 1)
                    {
                        //get next frame
                        WebPWrapper.WebPAnimDecoderGetNext(dec, out buf, out timestamp);
                        //copy frame into an Image (Bitmap)
                        bmp        = new Bitmap(imgWidth, imgHeight, PixelFormat.Format32bppArgb);
                        bmpData    = bmp.LockBits(new Rectangle(0, 0, imgWidth, imgHeight), ImageLockMode.WriteOnly, bmp.PixelFormat);
                        outputSize = (uint)(bmpData.Stride * imgHeight);
                        WebPWrapper.CopyMemory(bmpData.Scan0, buf, outputSize);
                        bmp.UnlockBits(bmpData);
                        //Add frame to the list
                        AddFrame(bmp, (timestamp - prevtimestamp) / 10);
                        prevtimestamp = timestamp;
                        bmpData       = null;
                        if (first)
                        {
                            ActiveImage = bmp;
                            Height      = imgHeight;
                            Width       = imgWidth;
                            first       = false;
                        }
                    }
                    WebPWrapper.WebPAnimDecoderReset(dec);
                    WebPWrapper.WebPAnimDecoderDelete(dec);
                    dec        = (IntPtr)0;
                    IsAnimated = true;
                }
                else
                {
                    //Create a Bitmap and Lock all pixels to be written
                    if (hasAlpha)
                    {
                        bmp = new Bitmap(imgWidth, imgHeight, PixelFormat.Format32bppArgb);
                    }
                    else
                    {
                        bmp = new Bitmap(imgWidth, imgHeight, PixelFormat.Format24bppRgb);
                    }
                    bmpData = bmp.LockBits(new Rectangle(0, 0, imgWidth, imgHeight), ImageLockMode.WriteOnly, bmp.PixelFormat);

                    //Uncompress the image
                    int outputSize = bmpData.Stride * imgHeight;
                    if (bmp.PixelFormat == PixelFormat.Format24bppRgb)
                    {
                        WebPWrapper.WebPDecodeBGRInto(ptrData, rawWebP.Length, bmpData.Scan0, outputSize, bmpData.Stride);
                    }
                    else
                    {
                        WebPWrapper.WebPDecodeBGRAInto(ptrData, rawWebP.Length, bmpData.Scan0, outputSize, bmpData.Stride);
                    }

                    ActiveImage = bmp;
                    Height      = imgHeight;
                    Width       = imgWidth;
                }
            }
            catch (Exception e) {
                GuiEngine.Current.log(e.ToString());
            }
            finally
            {
                //Unlock the pixels
                if (bmpData != null)
                {
                    bmp.UnlockBits(bmpData);
                }

                if (dec != (IntPtr)0)
                {
                    WebPWrapper.WebPAnimDecoderDelete(dec);
                }
                //Free memory
                if (pinnedWebP.IsAllocated)
                {
                    pinnedWebP.Free();
                }
            }
        }