一、Android圖片資源
在Android中,圖片資源通常放置在res/drawable目錄下。圖片資源存儲在圖片文件中,通常是在JPEG、PNG、GIF或者WebP格式中,這些圖片文件的大小和解析度都可能不一樣,而Android設備中的屏幕解析度也千差萬別,這就會導致在不同屏幕上顯示同樣的圖片可能會出現拉伸或壓縮的變形情況。
我們需要一種能夠針對不同解析度屏幕的圖片縮放方案,來提高用戶體驗並優化圖片顯示。
二、Android自帶的圖片縮放方案
Android提供了一種自動適應不同解析度的圖片適配方案,即為屏幕密度無關的單位dp。在res/drawable目錄下建立相同資源文件名的子目錄,並在子目錄下存放對應dpi的圖片,例如:
res/ drawable-mdpi/ icon.png drawable-hdpi/ icon.png drawable-xhdpi/ icon.png drawable-xxhdpi/ icon.png drawable-xxxhdpi/ icon.png
以上五個子目錄中的icon.png分別適用於不同的屏幕密度,其中:ldpi密度下不推薦使用。
當Android系統做圖片適配時,會去相應的dpi目錄下查找對應解析度的圖片,找到後自動按照設備的dpi進行縮放並顯示。
三、第三方庫Universal Image Loader
雖然Android自帶的圖片適配方案能夠適用於大多數情況,但是在某些場景下還是需要更靈活的圖片縮放方案來提高用戶體驗。比如,在列表中載入大量圖片時,每次載入圖片都需要重新拉伸或者壓縮,這樣極大地降低了用戶體驗。
在這種情況下,我們可以使用Universal Image Loader庫來進行圖片緩存和非同步載入,可以大幅度提高圖片的顯示效率,改善用戶體驗。
下面是Universal Image Loader的使用示例:
// 創建DisplayImageOptions對象並進行相關的配置 DisplayImageOptions options = new DisplayImageOptions.Builder() .cacheInMemory(true) // 開啟內存緩存 .cacheOnDisk(true) // 開啟硬碟緩存 .considerExifParams(true) // 考慮EXIF信息 .bitmapConfig(Bitmap.Config.RGB_565) // 設置圖片的解碼類型 .imageScaleType(ImageScaleType.IN_SAMPLE_INT) // 縮放類型 .build(); // 創建ImageLoader對象並進行相關配置 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .defaultDisplayImageOptions(options) // 設置默認的DisplayImageOptions對象 .threadPriority(Thread.NORM_PRIORITY - 2) // 線程優先順序 .denyCacheImageMultipleSizesInMemory() // 禁止緩存多個尺寸圖片在內存中 .diskCacheFileNameGenerator(new Md5FileNameGenerator()) // 硬碟緩存文件名生成器 .tasksProcessingOrder(QueueProcessingType.LIFO) // 圖片載入任務順序 .writeDebugLogs() // 調試輸出選項 .build(); // 初始化ImageLoader並進行相關操作 ImageLoader.getInstance().init(config); // 初始化 // 載入圖片 ImageView imageView = (ImageView) convertView.findViewById(R.id.image_view); String imageUrl = "http://www.example.com/image.png"; ImageLoader.getInstance().displayImage(imageUrl, imageView);
以上代碼中,創建DisplayImageOptions對象用於配置圖片顯示參數,其中設置了開啟內存和硬碟緩存、考慮EXIF信息、設置圖片的解碼類型和縮放類型等。
通過創建ImageLoaderConfiguration對象並進行各種配置,最後使用ImageLoader.getInstance()來初始化ImageLoader,然後再通過displayImage()方法進行圖片載入和顯示。
四、Android自帶的圖片壓縮方式
在一些特定的場景下,我們需要在程序中對圖片進行壓縮處理以節省內存空間,並提高程序運行的穩定性。Android提供了兩種方式對圖片進行壓縮處理:
第一種是使用BitmapFactory.Options的inSampleSize參數來為Bitmap對象指定一個整數縮放值,例如:
// 載入圖片的選項設置 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // 計算圖片的縮放比例 int width = options.outWidth; int height = options.outHeight; float maxWidth = 1024f; float maxHeight = 1024f; float scale = Math.min(maxWidth / width, maxHeight / height); int inSampleSize = Math.round(1 / scale); // 設置圖片載入選項的縮放比例 options.inJustDecodeBounds = false; options.inSampleSize = inSampleSize; // 載入原始的Bitmap並進行壓縮 Bitmap originBitmap = BitmapFactory.decodeFile(path, options); Bitmap compressedBitmap = Bitmap.createScaledBitmap(originBitmap, (int) (width * scale), (int) (height * scale), true); // 回收Bitmap對象並將其置為null originBitmap.recycle(); originBitmap = null; // 顯示壓縮後的Bitmap imageView.setImageBitmap(compressedBitmap);
以上代碼中,首先設置Bitmap載入選項的inJustDecodeBounds屬性為true,這會告訴BitmapFactory.decodeFile()方法只解析圖片的原始數據並不將其載入到內存中。接著計算圖片的縮放比例,並設置圖片載入選項的inJustDecodeBounds屬性為false以載入圖片,然後對原始Bitmap進行壓縮並回收原始的Bitmap對象。
第二種壓縮方式是使用Bitmap.compress()方法將原始Bitmap對象壓縮成JPEG或PNG格式存儲,代碼示例如下:
Bitmap originBitmap = BitmapFactory.decodeFile(path); ByteArrayOutputStream baos = new ByteArrayOutputStream(); originBitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos); byte[] bitmapBytes = baos.toByteArray(); Bitmap compressedBitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length, null); // 回收Bitmap對象並將其置為null originBitmap.recycle(); originBitmap = null; // 顯示壓縮後的Bitmap imageView.setImageBitmap(compressedBitmap);
以上代碼中,首先使用BitmapFactory.decodeFile()方法載入原始的Bitmap對象,然後將其壓縮為JPEG格式的圖像,並使用ByteArrayOutputStream將其以位元組數組的形式返回。接著使用BitmapFactory.decodeByteArray()方法將位元組數組解碼成Bitmap對象並顯示在ImageView中。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/231670.html