From b066b8c503930fcded005fc3eb6464a3ad5c82f8 Mon Sep 17 00:00:00 2001 From: jacpy Date: Tue, 12 Dec 2017 15:09:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BD=BF=E7=94=A8png?= =?UTF-8?q?=E5=A4=A7=E5=9B=BE=E6=97=B6=EF=BC=8C=E4=B8=80=E7=9B=B4=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=9A=84=E6=98=AF=E7=BC=A9=E7=95=A5=E5=9B=BE=EF=BC=8C?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=98=BE=E7=A4=BA=E5=8E=9F=E5=9B=BE=E3=80=82?= =?UTF-8?q?=20=E5=8E=9F=E5=9B=A0=EF=BC=9A=E5=A6=82=E6=9E=9C=E6=98=AFPNG?= =?UTF-8?q?=E5=A4=A7=E5=9B=BE=E8=B0=83=E7=94=A8BitmapRegionDecoder.decodeR?= =?UTF-8?q?egion()=E4=BC=A0=E5=8F=82Bitmap.Options=E4=BD=BF=E7=94=A8Bitmap?= =?UTF-8?q?.Config.RGB=5F565=E6=97=B6=EF=BC=8Cdecode=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E4=B8=BAnull=EF=BC=8C=E4=BD=BF=E7=94=A8Bitmap.Config.ARGB=5F88?= =?UTF-8?q?88=E5=90=8EOK=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/largeimage/BlockImageLoader.java | 80 ++++++++++++------- .../factory/BitmapDecoderFactory.java | 3 +- .../factory/FileBitmapDecoderFactory.java | 4 +- .../InputStreamBitmapDecoderFactory.java | 6 +- 4 files changed, 56 insertions(+), 37 deletions(-) diff --git a/library/src/main/java/com/shizhefei/view/largeimage/BlockImageLoader.java b/library/src/main/java/com/shizhefei/view/largeimage/BlockImageLoader.java index d3534bb..0509771 100644 --- a/library/src/main/java/com/shizhefei/view/largeimage/BlockImageLoader.java +++ b/library/src/main/java/com/shizhefei/view/largeimage/BlockImageLoader.java @@ -19,6 +19,7 @@ import android.graphics.Rect; import android.os.Build; import android.support.v4.util.Pools; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseIntArray; @@ -44,7 +45,9 @@ public class BlockImageLoader { public static boolean DEBUG = false; static final String TAG = "Loader"; - private static Pools.SynchronizedPool bitmapPool = new Pools.SynchronizedPool<>(6); + private static final String IMAGE_PNG = "png"; + + private Pools.SynchronizedPool bitmapPool = new Pools.SynchronizedPool<>(6); private Pools.SimplePool blockDataPool = new Pools.SimplePool<>(64); private Pools.SimplePool drawDataPool = new Pools.SimplePool<>(64); private LoadData mLoadData; @@ -141,15 +144,15 @@ public void loadImageBlocks(List drawDataList, float imageScale, Rect } drawDataList.clear(); - if (loadData.mDecoder == null) { + if (loadData.mDecoder == null || loadData.options == null) { if (isUnRunning(loadData.task)) { loadData.task = new LoadImageInfoTask(loadData, onImageLoadListener, onLoadStateChangeListener); exeTask(loadData.task); } return; } - int imageWidth = loadData.imageWidth; - int imageHeight = loadData.imageHeight; + int imageWidth = loadData.options.outWidth; + int imageHeight = loadData.options.outHeight; BitmapRegionDecoder decoder = loadData.mDecoder; if (loadData.thumbnailBlockData == null) { int screenWidth = context.getResources().getDisplayMetrics().widthPixels; @@ -377,7 +380,7 @@ public void loadImageBlocks(List drawDataList, float imageScale, Rect for (int col = startCol; col < endCol; col++) { positionKey.set(row, col); //blockData可能为null - BlockData blockData = addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder); + BlockData blockData = addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder, loadData.options); Bitmap bitmap = blockData.bitmap; if (bitmap != null) { DrawData drawData = drawDataPool.acquire(); @@ -412,14 +415,14 @@ public void loadImageBlocks(List drawDataList, float imageScale, Rect for (int row = cacheStartRow; row < startRow; row++) { for (int col = cacheStartCol; col < cacheEndCol; col++) { positionKey.set(row, col); - addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder); + addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder, loadData.options); } } // 下 ######### for (int row = endRow; row < cacheEndRow; row++) { for (int col = cacheStartCol; col < cacheEndCol; col++) { positionKey.set(row, col); - addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder); + addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder, loadData.options); } } // # 左 @@ -427,7 +430,7 @@ public void loadImageBlocks(List drawDataList, float imageScale, Rect for (int row = startRow; row < endRow; row++) { for (int col = cacheStartCol; col < startCol; col++) { positionKey.set(row, col); - addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder); + addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder, loadData.options); } } // # 右 @@ -435,7 +438,7 @@ public void loadImageBlocks(List drawDataList, float imageScale, Rect for (int row = startRow; row < endRow; row++) { for (int col = endCol; col < cacheEndCol; col++) { positionKey.set(row, col); - addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder); + addRequestBlock(positionKey, tempCurrentDataMap.get(positionKey), loadData.currentScaleDataMap, scale, imageWidth, imageHeight, decoder, loadData.options); } } //移除掉那些没被用到的缓存的图片块 @@ -592,7 +595,7 @@ private void recycleBlock(BlockData block) { blockDataPool.release(block); } - private BlockData addRequestBlock(Position positionKey, BlockData blockData, Map currentDataMap, int scale, int imageWidth, int imageHeight, BitmapRegionDecoder decoder) { + private BlockData addRequestBlock(Position positionKey, BlockData blockData, Map currentDataMap, int scale, int imageWidth, int imageHeight, BitmapRegionDecoder decoder, BitmapFactory.Options options) { if (blockData == null) { blockData = blockDataPool.acquire(); if (blockData == null) { @@ -606,7 +609,7 @@ private BlockData addRequestBlock(Position positionKey, BlockData blockData, Map } } if (blockData.bitmap == null && isUnRunning(blockData.task)) { - blockData.task = new LoadBlockTask(blockData.position, blockData, scale, imageWidth, imageHeight, decoder, onImageLoadListener, onLoadStateChangeListener); + blockData.task = new LoadBlockTask(blockData.position, blockData, scale, imageWidth, imageHeight, decoder, options, onImageLoadListener, onLoadStateChangeListener); exeTask(blockData.task); } currentDataMap.put(blockData.position, blockData); @@ -641,17 +644,17 @@ static int dip2px(Context context, float dipValue) { } int getWidth() { - if (mLoadData == null) { + if (mLoadData == null || mLoadData.options == null) { return 0; } - return mLoadData.imageWidth; + return mLoadData.options.outWidth; } int getHeight() { - if (mLoadData == null) { + if (mLoadData == null || mLoadData.options == null) { return 0; } - return mLoadData.imageHeight; + return mLoadData.options.outHeight; } private static class LoadData { @@ -678,9 +681,8 @@ private static class LoadData { private BitmapDecoderFactory mFactory; private BitmapRegionDecoder mDecoder; - private int imageHeight; - private int imageWidth; private LoadImageInfoTask task; + private BitmapFactory.Options options; LoadData(BitmapDecoderFactory factory) { mFactory = factory; @@ -765,8 +767,7 @@ private static class LoadImageInfoTask extends TaskQueue.Task { private OnLoadStateChangeListener onLoadStateChangeListener; private OnImageLoadListener onImageLoadListener; private volatile BitmapRegionDecoder decoder; - private volatile int imageWidth; - private volatile int imageHeight; + private volatile BitmapFactory.Options options; private volatile Exception e; LoadImageInfoTask(LoadData loadData, OnImageLoadListener onImageLoadListener, OnLoadStateChangeListener onLoadStateChangeListener) { @@ -775,6 +776,13 @@ private static class LoadImageInfoTask extends TaskQueue.Task { this.onImageLoadListener = onImageLoadListener; this.onLoadStateChangeListener = onLoadStateChangeListener; if (DEBUG) { + int imageWidth = 0; + int imageHeight = 0; + if (options != null) { + imageWidth = options.outWidth; + imageHeight = options.outHeight; + } + Log.d(TAG, "start LoadImageInfoTask:imageW:" + imageWidth + " imageH:" + imageHeight); } } @@ -791,8 +799,7 @@ protected void onPreExecute() { protected void doInBackground() { try { decoder = mFactory.made(); - imageWidth = decoder.getWidth(); - imageHeight = decoder.getHeight(); + options = mFactory.getImageInfo(); if (DEBUG) { Log.d(TAG, "LoadImageInfoTask doInBackground"); } @@ -818,14 +825,20 @@ protected void onCancelled() { protected void onPostExecute() { super.onPostExecute(); if (DEBUG) { + int imageWidth = 0; + int imageHeight = 0; + if (options != null) { + imageWidth = options.outWidth; + imageHeight = options.outHeight; + } + Log.d(TAG, "onPostExecute LoadImageInfoTask:" + e + " imageW:" + imageWidth + " imageH:" + imageHeight + " e:" + e); } imageInfo.task = null; - if (e == null) { - imageInfo.imageWidth = imageWidth; - imageInfo.imageHeight = imageHeight; + if (e == null && this.options != null) { + imageInfo.options = this.options; imageInfo.mDecoder = decoder; - onImageLoadListener.onLoadImageSize(imageWidth, imageHeight); + onImageLoadListener.onLoadImageSize(this.options.outWidth, this.options.outHeight); } else { onImageLoadListener.onLoadFail(e); } @@ -839,10 +852,11 @@ protected void onPostExecute() { } } - private static class LoadBlockTask extends TaskQueue.Task { + private class LoadBlockTask extends TaskQueue.Task { private int scale; private BlockData blockData; private Position position; + private BitmapFactory.Options options; private int imageWidth; private int imageHeight; private BitmapRegionDecoder decoder; @@ -852,13 +866,14 @@ private static class LoadBlockTask extends TaskQueue.Task { private volatile Bitmap bitmap; private volatile Throwable throwable; - LoadBlockTask(Position position, BlockData blockData, int scale, int imageWidth, int imageHeight, BitmapRegionDecoder decoder, OnImageLoadListener onImageLoadListener, OnLoadStateChangeListener onLoadStateChangeListener) { + LoadBlockTask(Position position, BlockData blockData, int scale, int imageWidth, int imageHeight, BitmapRegionDecoder decoder, BitmapFactory.Options options, OnImageLoadListener onImageLoadListener, OnLoadStateChangeListener onLoadStateChangeListener) { this.blockData = blockData; this.scale = scale; this.position = position; this.imageWidth = imageWidth; this.imageHeight = imageHeight; this.decoder = decoder; + this.options = options; this.onImageLoadListener = onImageLoadListener; this.onLoadStateChangeListener = onLoadStateChangeListener; if (DEBUG) { @@ -894,7 +909,12 @@ protected void doInBackground() { try { BitmapFactory.Options decodingOptions = new BitmapFactory.Options(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - Bitmap bitmap = acquireBitmap(); + Bitmap.Config config = Bitmap.Config.RGB_565; + if (!TextUtils.isEmpty(options.outMimeType) && options.outMimeType.contains(IMAGE_PNG)) { + config = Bitmap.Config.ARGB_8888; + } + + Bitmap bitmap = acquireBitmap(config); decodingOptions.inBitmap = bitmap; decodingOptions.inMutable = true; } @@ -954,10 +974,10 @@ protected void onPostExecute() { } } - private static Bitmap acquireBitmap() { + private Bitmap acquireBitmap(Bitmap.Config config) { Bitmap bitmap = bitmapPool.acquire(); if (bitmap == null) { - bitmap = Bitmap.createBitmap(BASE_BLOCKSIZE, BASE_BLOCKSIZE, Bitmap.Config.RGB_565); + bitmap = Bitmap.createBitmap(BASE_BLOCKSIZE, BASE_BLOCKSIZE, config); } return bitmap; } diff --git a/library/src/main/java/com/shizhefei/view/largeimage/factory/BitmapDecoderFactory.java b/library/src/main/java/com/shizhefei/view/largeimage/factory/BitmapDecoderFactory.java index dc6b48b..7e15ae8 100644 --- a/library/src/main/java/com/shizhefei/view/largeimage/factory/BitmapDecoderFactory.java +++ b/library/src/main/java/com/shizhefei/view/largeimage/factory/BitmapDecoderFactory.java @@ -1,10 +1,11 @@ package com.shizhefei.view.largeimage.factory; +import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import java.io.IOException; public interface BitmapDecoderFactory { BitmapRegionDecoder made() throws IOException; - int[] getImageInfo(); + BitmapFactory.Options getImageInfo(); } \ No newline at end of file diff --git a/library/src/main/java/com/shizhefei/view/largeimage/factory/FileBitmapDecoderFactory.java b/library/src/main/java/com/shizhefei/view/largeimage/factory/FileBitmapDecoderFactory.java index 160afeb..c62b2de 100644 --- a/library/src/main/java/com/shizhefei/view/largeimage/factory/FileBitmapDecoderFactory.java +++ b/library/src/main/java/com/shizhefei/view/largeimage/factory/FileBitmapDecoderFactory.java @@ -25,10 +25,10 @@ public BitmapRegionDecoder made() throws IOException { } @Override - public int[] getImageInfo() { + public BitmapFactory.Options getImageInfo() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); - return new int[]{options.outWidth, options.outHeight}; + return options; } } \ No newline at end of file diff --git a/library/src/main/java/com/shizhefei/view/largeimage/factory/InputStreamBitmapDecoderFactory.java b/library/src/main/java/com/shizhefei/view/largeimage/factory/InputStreamBitmapDecoderFactory.java index f149bf0..e4d0496 100644 --- a/library/src/main/java/com/shizhefei/view/largeimage/factory/InputStreamBitmapDecoderFactory.java +++ b/library/src/main/java/com/shizhefei/view/largeimage/factory/InputStreamBitmapDecoderFactory.java @@ -7,8 +7,6 @@ import java.io.IOException; import java.io.InputStream; -import static android.R.attr.path; - public class InputStreamBitmapDecoderFactory implements BitmapDecoderFactory { private InputStream inputStream; @@ -23,10 +21,10 @@ public BitmapRegionDecoder made() throws IOException { } @Override - public int[] getImageInfo() { + public BitmapFactory.Options getImageInfo() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(inputStream, new Rect(),options); - return new int[]{options.outWidth, options.outHeight}; + return options; } } \ No newline at end of file