2017-07-18 52 views
9

我使用滑行提取從緩存中的位圖,並將其保存在其他地方。下面的相關函數(根據此post :)無法觸發提取。實際上,日誌行'Log.d(TAG,「即將開始提取」);''下面永遠不會被觸發。滑翔圖像截取

爲什麼簡單的目標函數不會被調用任何想法?

public byte[] extractImageFromCache(Context context, String pictureURL) { 

    byte[] byteArray = new byte[0]; 
    if (context != null && pictureURL != null && !pictureURL.isEmpty()) { 

     final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 

     Glide.with(context) 
      .load(pictureURL) 
      .asBitmap() 
      .toBytes() 
      .diskCacheStrategy(DiskCacheStrategy.SOURCE) // Load the original hires image 
      .into(new SimpleTarget<byte[]>() { 
       @Override public void onResourceReady(final byte[] resource, GlideAnimation<? super byte[]> glideAnimation) { 
        Log.d(TAG, "About to start extraction"); 
        new AsyncTask<Void, Void, Void>() { 
         @Override protected Void doInBackground(Void... params) { 
          Log.d(TAG, "Start extraction"); 
          try { 
           Log.d(TAG, "Image bytes len: " + resource.length); 
           byteArrayOutputStream.write(resource); 
           byteArrayOutputStream.flush(); 
          } catch (IOException e) { 
           e.printStackTrace(); 
           Log.i(TAG, "Unable to load image: " + pictureURL); 
           e.printStackTrace(); 
          } 
          return null; 
         } 
        }.execute(); 

       } 
      }); 
     Log.d(TAG, String.format("Got image bytes: %d for %s", byteArrayOutputStream.size(), pictureURL)); 
     return byteArrayOutputStream.toByteArray(); 
    } 
    return null; 
} 
+0

你能後的logcat的? – azizbekian

+0

你在哪裏調用這個函數? – rom4ek

+0

提及Glide版本,我試過了你的代碼,它在'glide:3.7.0' – Maddy

回答

1

首先,您的返回無效,因爲Glide在異步線程中執行請求。所以byteArrayOutputStream永遠不會在函數返回之前及時填充。這意味着你的函數將總是返回一個空的字節數組。這也意味着您的日誌語句Log.d(TAG, String.format("Got image bytes: %d for %s", byteArrayOutputStream.size(), pictureURL));將無效。知道這一點後,您的About to start extraction將出現在Got image bytes...之後。您將需要重新格式化您的代碼以使用回調來通知調用者您的代碼已檢索數組的函數。事情是這樣的:

public interface GlideByteLoadCallback { 
    void onBytesExtracted(byte[] bytes); 
    void onFail(String message); 
} 

public void extractImageFromCache(Context context, String pictureURL, GlideByteLoadCallback callback) { 

    if (context != null && pictureURL != null && !pictureURL.isEmpty()) { 

     final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 

     Glide.with(context) 
      .load(pictureURL) 
      .asBitmap() 
      .toBytes() 
      .diskCacheStrategy(DiskCacheStrategy.SOURCE) // Load the original hires image 
      .into(new SimpleTarget<byte[]>() { 
       @Override public void onResourceReady(final byte[] resource, GlideAnimation<? super byte[]> glideAnimation) { 
        Log.d(TAG, "About to start extraction"); 
        new AsyncTask<Void, Void, Void>() { 
         @Override protected Void doInBackground(Void... params) { 
          Log.d(TAG, "Start extraction"); 
          try { 
           Log.d(TAG, "Image bytes len: " + resource.length); 
           byteArrayOutputStream.write(resource); 

           byteArrayOutputStream.flush(); 
           if (callback != null) callback.onBytesExtracted(byteArrayOutputStream.toByteArray()); 
          } catch (IOException e) { 
           e.printStackTrace(); 
           Log.i(TAG, "Unable to load image: " + pictureURL); 
           e.printStackTrace(); 
           if (callback != null) callback.onFail("Extraction failed"); 
          } 
         } 
        }.execute(); 
       } 
      }); 
    } 
    if (callback != null) callback.onFail("Invalid url"); 
} 

然後調用它:

extractImageFromCache(context, picture, new GlideByteLoadCallback() { 
       @Override 
       public void onFail(String message) { 
        // handle failure here 
       } 

       @Override 
       public void onBytesExtracted(byte[] bytes) { 
        // do stuff with bytes here 
       } 
      }); 
0

這是我會怎麼做。

當您使用的滑行,將您加載圖像的成像圖。

從代碼,設置:

imageView = (ImageView) view.findViewById(R.id.image_view); 
imageViewProfile.setDrawingCacheEnabled(true); 
imageViewProfile.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); 

然後從那個圖像視圖的位圖,你可以使用

imageView.getDrawingCache() //This returns a Bitmap 

你應該擔心的唯一的事情是驗證滑翔裝完你圖像與否 - 我不知道如何完成這一點,但試試看,如果這對你有用,就投票。

2

通過使用SimpleTarget對象,我們就可以輕鬆搞定,我們正在努力,因爲默認情況下,滑翔找緩存命中從緩存中或網絡中提取位圖。

修改你的滑翔加載代碼這樣:

 Glide.with(this) 
      .load("https://cdn-images-1.medium.com/max/1200/1*hcfIq_37pabmAOnw3rhvGA.png") 
      .asBitmap() 
      .diskCacheStrategy(DiskCacheStrategy.SOURCE) 
      .into(new SimpleTarget<Bitmap>() { 
       @Override 
       public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { 
        Log.d("Size ", "width :"+resource.getWidth() + " height :"+resource.getHeight()); 
        imageView.setImageBitmap(resource); 
        storeImage(resource); 
       } 
      }); 

,並使用或任何其他機制來存儲位圖到外部/內部存儲。

private void storeImage(Bitmap image) { 
     File pictureFile = getOutputMediaFile(); 
     if (pictureFile == null) { 
      Log.d(TAG, 
        "Error creating media file, check storage permissions: ");// e.getMessage()); 
      return; 
     } 
     try { 
      FileOutputStream fos = new FileOutputStream(pictureFile); 
      image.compress(Bitmap.CompressFormat.PNG, 90, fos); 
      fos.close(); 
      Log.d(TAG, "img dir: " + pictureFile); 
     } catch (FileNotFoundException e) { 
      Log.d(TAG, "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d(TAG, "Error accessing file: " + e.getMessage()); 
     } 
    } 


private File getOutputMediaFile(){ 
    // To be safe, you should check that the SDCard is mounted 
    // using Environment.getExternalStorageState() before doing this. 
    File mediaStorageDir = new File(Environment.getExternalStorageDirectory() 
      + "/Android/data/" 
      + getApplicationContext().getPackageName() 
      + "/Files"); 

    if (! mediaStorageDir.exists()){ 
     if (! mediaStorageDir.mkdirs()){ 
      return null; 
     } 
    } 

    File mediaFile; 
    Random generator = new Random(); 
    int n = 1000; 
    n = generator.nextInt(n); 
    String mImageName = "Image-"+ n +".jpg"; 

    mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName); 
    return mediaFile; 
} 

我使用的Glide版3.7

compile "com.github.bumptech.glide:glide:3.7.0" 

這裏充滿工作示例:https://github.com/nieldeokar/GlideApp

3

正如你所提到的,Log.d(TAG, 「關於啓動提取」)從未被觸發,這意味着onResourceReady永遠不會被調用。這可能由於某種錯誤而發生。嘗試覆蓋錯誤回調。

要確定我會建議您覆蓋SimpleTarget的其他回調調試問題的問題。

@Override 
    public void onLoadCleared(@Nullable Drawable placeholder) { 
    // load has been cleared 
    } 

    @Override 
    public void onLoadStarted(@Nullable Drawable placeholder) { 
    // load has started 
    } 

    @Override 
    public void onLoadFailed(@Nullable Drawable errorDrawable) { 
    // load failed due to some reason, notify callers here about the same 
    }