2017-07-18 5 views
9

Ich benutze Glide, um eine Bitmap aus dem Cache zu extrahieren und an anderer Stelle zu speichern. Die entsprechende Funktion (basierend auf dieser post :) löst die Extraktion nicht aus. In der Tat, die Log-Zeile 'Log.d (TAG, "um die Extraktion zu starten");' unten wird nie ausgelöst.Glide Bildextraktion

Irgendwelche Ideen, warum die einfache Zielfunktion nie aufgerufen wird?

+0

Können Sie den Logcat posten? – azizbekian

+0

Wo nennst du diese Funktion? – rom4ek

+0

Erwähnen Glide-Version, ich habe Ihren Code versucht und es funktioniert perfekt in 'gleiten: 3.7.0' – Maddy

Antwort

1

Zunächst ist Ihre Rückgabe ungültig, weil Glide die Anforderung in einem asynchronen Thread ausführt. So wird byteArrayOutputStream nie rechtzeitig gefüllt, bevor die Funktion zurückkehrt. Dies bedeutet, dass Ihre Funktion immer ein leeres Byte-Array zurückgibt. Dies bedeutet auch, dass Ihre Log-Anweisung Log.d(TAG, String.format("Got image bytes: %d for %s", byteArrayOutputStream.size(), pictureURL)); ungültig ist. Wenn Sie dies wissen, wird Ihr nach Got image bytes... angezeigt. Sie müssen Ihren Code neu formatieren, um Callbacks zu verwenden, um den Aufrufer der Funktion zu benachrichtigen, dass Ihr Code das Array abgerufen hat. Etwas wie folgt aus:

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"); 
} 

Dann rufen Sie es mit:

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

Dies ist, was ich tun würde.

Während Sie Gleitflug verwenden, legen Sie das geladene Bild in eine Bildansicht.

Von Code setzen:

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

dann die Bitmap aus dieser Bildansicht gelangen Sie

imageView.getDrawingCache() //This returns a Bitmap 

Das einzige, was Sie sollten Sorge verwenden können, ist zu überprüfen, ob Glide Laden fertig Ihre Bild oder nicht - ich bin mir nicht sicher, wie ich das erreichen soll -, aber geben Sie einen Versuch und geben Sie eine Stimme, wenn das für Sie funktioniert.

2

Mit SimpleTarget Objekt können wir leicht Bitmap erhalten, die wir aus dem Cache oder Netzwerk extrahieren wollen, da glide standardmäßig nach Cache-Treffern sucht.

Ihre Glide Ladecode dazu ändern:

 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); 
       } 
      }); 

Und mit diesem oder irgendeinem anderen Mechanismus für Bitmap zu externen/internen Speicher speichert.

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; 
} 

I Glide bin mit ver 3.7

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

Hier ist voll funktionierendes Beispiel: https://github.com/nieldeokar/GlideApp

3

Wie Sie erwähnt haben, Log.d (TAG "Über Extraktion starten") nie wird ausgelöst, was bedeutet, dass onResourceReady nie aufgerufen wird. Dies könnte aufgrund eines Fehlers passieren. Überschreiben Sie Fehlerrückrufe.

Um das Problem zu identifizieren, würde ich empfehlen, andere Callbacks von SimpleTarget zu überschreiben, um das Problem zu debuggen.

@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 
    }