Image Corruption With Caching on Xamarin.Forms Android

NicholasVentimigliaNicholasVentimiglia USMember ✭✭
edited August 2015 in Xamarin.Forms

Here is my source code.
https://gist.github.com/NVentimiglia/2285c8ea452dbe2d4714

In short, when I cache an image, it becomes corrupted (mono-color)

Here is a ContentView which includes a spinner and a image encapsulated in a grid. It has one main bindable property, source, which accepts a string uri. When bound, the content view shows a spinner while loading the image in the background using a "CachedHttpClient" (included). This client will first check Personal Storage and return the byte[] if found. If not it will return a byte[] from an async request. Once completed, the bytes are passed to native to be re-sized to the exact size of the control and then passed to the child image as an image source.

The first time this runs It works perfectly, however, when I reload the view the image is corrupted. I see a mono-color (grey or blue blobs... an amalgamation of all pixels ?) in place of the image.

My instincts tell me my I/O logic is wrong but... it is dead simple.

        public void Write(string fname, byte[] data)
        {
            lock (_syncLock)
            {
                var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), Group);

                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);


                var filePath = Path.Combine(path, fname);
                File.WriteAllBytes(filePath, data);

                //Not working either
                //var base64String = Convert.ToBase64String(data);
                //File.WriteAllText(filePath, base64String);


            }
        }
    public byte[] Read(string fname)
        {
            lock (_syncLock)
            {

                var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), Group);

                if (!Directory.Exists(path))
                    return null;

                var filePath = Path.Combine(path, fname);

                if (!File.Exists(filePath))
                    return null;

                //Not working either
                // var data = File.ReadAllText(filePath);
                //return Convert.FromBase64String(data);

                //Not working
                return File.ReadAllBytes(filePath);
            }
        }

Next I looked at my image resizeing method

    public byte[] ResizeImage(byte[] imageData, int width, int height)
        {
            // Load the bitmap
            using (Bitmap originalImage = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length))
            {
                using (Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, false))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        resizedImage.Compress(Bitmap.CompressFormat.Png, 95, ms);
                        return ms.ToArray();
                    }
                }
            }
        }

I have read reports of android image bugs. Any links to bug reports or workarounds would be appreciated.

Posts

  • Solved.

    The issue was with my cache. It was not writing because my filename was just the url (with the special characteristic). The solution is to convert the filename to base64 for the cache.

Sign In or Register to comment.