jueves, 10 de marzo de 2011

Desplegar imagenes GIF en Windows Phone 7, usando C#

Actualmente el Windows Phone 7, no soporta el renderizado de imágenes GIF debido a que usa Silverlight, por lo que es útil, el uso de algún decodificador de imágenes, ya sea que lo escribamos o utilicemos alguno de los ya disponibles.




Para este ejemplo en particular utilice el ImageTools.



Paso 1 - Descargar/escribir la librería para la de-codificación de imágenes GIF.






Paso 2 - Agregar las referencias al proyecto






Paso 3 - Obtener el stream de la imagen
Esto puede ser desde una URL, desde el Isolated Storage, o desde un Recurso de aplicación, para este ejemplo se muestran tanto el de recurso de aplicación como el de URI de internet.



private static WebClient proxy;

        public delegate void ImageReceivedDelegate(Stream stream);
        public static event ImageReceivedDelegate ImageReceived;

      

        /// <summary>
        /// Get a Image Stream from a resource
        /// </summary>
        /// <param name="filename">File Name</param>
        /// <param name="imagelocation">Image Path</param>
        /// <returns></returns>
        public static Stream GetImageStream(string filename, string imagelocation)
        {
            StreamResourceInfo imageResource = Application.GetResourceStream(new Uri(imagelocation + filename, UriKind.Relative));
           
            return imageResource.Stream;
        }
        /// <summary>
        /// Get a Image stream from a internet URI
        /// </summary>
        /// <param name="uri"></param>
        public static void GetImageStream(string uri)
        {

            try {
                proxy = new WebClient();
                proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted);
                proxy.OpenReadAsync(new Uri(uri));

            }

            catch {
           
            }
        }
        /// <summary>
        /// Event Handler to process the open_read completed event, this bubble the event using a delegate
        /// to throw out the file stream
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {

                proxy = null;
          
                if (ImageReceived != null)
                {
                  
                    ImageReceived(e.Result);
                }
          
        }






Paso 4 - Decodificar la imagen


En el constructor o en un evento de carga de la pagina, asociar un manejador del evento para ImageReceived.

ImageHandler.ImageReceived += new ImageHandler.ImageReceivedDelegate(ImageHandler_ImageReceived);

Implementar el manejador del evento

void ImageHandler_ImageReceived(System.IO.Stream stream)
        {
            try
            {
                var img = new ImageTools.ExtendedImage ();
                var dec = new ImageTools.IO.Gif.GifDecoder();
                dec.Decode(img, stream);

                 /*TODO*/

                
            }
            catch (Exception ex)
            {

            }
            finally {
                stream.Close();
            }
           
        }



Paso 5 - Convertir la imagen en un bitmap, usando el WritableBitmap
/// <summary>
        /// Converts a ImageBase into a WritableBitmap, usable when we need to convert images between formats
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static WriteableBitmap ToBitmap(ImageTools.ImageBase image)
        {

            ImageTools.ImageBase temp = image;
            var bitmap = new WriteableBitmap(image.PixelWidth, image.PixelHeight);
            byte[] pixels = temp.Pixels;
            int[] raster = bitmap.Pixels;
            Buffer.BlockCopy(pixels, 0, raster, 0, pixels.Length);
            for (int i = 0; i < raster.Length; i++)
            {
                int abgr = raster[i];
                int a = (abgr >> 24) & 0xff;
                float m = a / 255f;
                int argb = a << 24 |
                          (int)((abgr & 0xff) * m) << 16 |
                          (int)(((abgr >> 8) & 0xff) * m) << 8 |
                          (int)(((abgr >> 16) & 0xff) * m);
                raster[i] = argb;
            }
            bitmap.Invalidate();
            return bitmap;
        }



Paso 6 - Enlazar el bitmap a un control de imagen

void ImageHandler_ImageReceived(System.IO.Stream stream)
        {
            try
            {
                var img = new ImageTools.ExtendedImage ();
                var dec = new ImageTools.IO.Gif.GifDecoder();
                dec.Decode(img, stream);

                image1.Source = ToBitmap(img);

                
            }
            catch (Exception ex)
            {

            }
            finally {
                stream.Close();
            }
           
        }

Transacciones Fiori

  /UI2/CACHE Register service for UI2 cache use /UI2/CACHE_DEL Delete cache entries /UI2/CHIP Chip Registration /UI2/CUST Customizing of UI ...