官术网_书友最值得收藏!

  • Xamarin Blueprints
  • Michael Williams
  • 555字
  • 2021-07-08 11:48:20

Bitmap functions

What about the byte data? First, let's implement our BitmapHelpers; these will include two global functions to help with bitmap processing:

public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) 
        { 
            // Raw height and width of image 
            float height = options.OutHeight; 
            float width = options.OutWidth; 
            double inSampleSize = 1D; 
 
            if (height > reqHeight || width > reqWidth) 
            { 
                int halfHeight = (int)(height / 2); 
                int halfWidth = (int)(width / 2); 
 
                // Calculate a inSampleSize that is a power of 2 - the decoder will use a value that is a power of two anyway. 
                while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) 
                { 
                    inSampleSize *= 2; 
                } 
            } 
 
            return (int)inSampleSize; 
        } 
 
        public static async void CreateBitmap(ImageView imageView, byte[] imageData) 
        { 
            try 
            { 
                if (imageData != null)  
                { 
                    var bm = await BitmapFactory.DecodeByteArrayAsync(imageData, 0, imageData.Length); 
                    if (bm != null)  
                    { 
                        imageView.SetImageBitmap(bm); 
                    } 
                } 
            } 
            catch (Exception e)  
            { 
                Console.WriteLine ("Bitmap creation failed: " + e); 
            } 
        } 

Our first function will determine the best sample size by the requested width and height. This is a very good technique for reducing the resources required to load an image into memory. Our next function is used to create a bitmap for the ImageView that is passed in from the byte data.

The next step is to create this image data using the private method createCompressedImageDataFromBitmap:

private static byte[] createCompressedImageDataFromBitmap(string url) 
        { 
            BitmapFactory.Options options = new BitmapFactory.Options (); 
            options.InJustDecodeBounds = true; 
            BitmapFactory.DecodeFile (url, options); 
            options.InSampleSize = BitmapHelpers.CalculateInSampleSize (options, 1600, 1200); 
            options.InJustDecodeBounds = false; 
 
            Bitmap bm = BitmapFactory.DecodeFile (url, options); 
 
            var stream = new MemoryStream (); 
            bm.Compress (Bitmap.CompressFormat.Jpeg, 80, stream); 
            return stream.ToArray (); 
        } 

This method will take the image URI and decode the bitmap options in order to sample the smallest possible size for the dimensions provided.

We have to make sure that we flag InJustDecodeBounds so this bitmap is not loaded into memory while we are retrieving the options information. This approach is very useful for reducing images to the size we require, thus saving memory. We then compress the image by 80% into a JPEG and convert the stream into a byte array for our GalleryItem model.

Now let's go back to the adapter class and add this method to fill in the items of our ListAdapter:

public ListAdapter(Activity context) : base() 
        { 
            _context = context; 
            _items = new List<GalleryItem>(); 
 
            foreach (var galleryitem in ImageHandler.GetFiles (_context)) 
            { 
                _items.Add (galleryitem); 
            } 
        } 

Note

Remember we must have a reference in our list adapter to the main context.

Now for the final piece of the puzzle, connecting the adapter to our list view. Open up the MainActivity.cs file and update the code list like so:

public class MainActivity : Activity 
    { 
        private ListAdapter _adapter; 
 
        protected override void OnCreate (Bundle savedInstanceState) 
        { 
            base.OnCreate (savedInstanceState); 
 
            SetContentView (Resource.Layout.Main); 
 
            _adapter = new ListAdapter (this); 
 
            var listView = FindViewById<ListView> (Resource.Id.listView); 
            listView.Adapter = adapter; 
        } 
    } 

And voila! Try running the application and watching the ListView update with the images in your device's Gallery folder. Congratulations! You have just developed your first Xamarin.Android application. Now we must replicate this approach for the iOS version.

Note

Notice the challenge with context switching when jumping back and forth between Android and iOS; it can get confusing. Luckily, with Xamarin we keep to just one programming language, which helps reduce the complexity.

主站蜘蛛池模板: 施甸县| 乐清市| 虹口区| 微山县| 汉沽区| 崇州市| 句容市| 平塘县| 舒城县| 扎囊县| 栖霞市| 凤山市| 泰安市| 建始县| 宜良县| 卢龙县| 汝城县| 门头沟区| 巴东县| 邓州市| 弥勒县| 桐梓县| 白水县| 武宣县| 安吉县| 淮阳县| 高陵县| 翼城县| 徐水县| 石家庄市| 永胜县| 兴安县| 武冈市| 应城市| 芦山县| 岳阳市| 绍兴市| 铜梁县| 泰州市| 桓仁| 安岳县|