2017-07-18 16 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

क्या आप लॉगकैट पोस्ट कर सकते हैं? – azizbekian

+0

आप इस समारोह को कहां कॉल करते हैं? – rom4ek

+0

ग्लाइड संस्करण का उल्लेख करें, मैंने आपके कोड की कोशिश की है और यह पूरी तरह से 'ग्लाइड: 3.7.0' – Maddy

उत्तर

1

सबसे पहले, आपकी वापसी अमान्य है क्योंकि ग्लाइड एक एसिंक्रोनस थ्रेड में अनुरोध निष्पादित करता है। इसलिए byteArrayOutputStream फ़ंक्शन रिटर्न से पहले समय में कभी भी पॉप्युलेट नहीं होता है। इसका मतलब है कि आपका फ़ंक्शन हमेशा खाली बाइट सरणी वापस कर देगा। इसका मतलब यह भी है कि आपका लॉग स्टेटमेंट Log.d(TAG, String.format("Got image bytes: %d for %s", byteArrayOutputStream.size(), pictureURL)); अमान्य होगा। यह जानकर, About to start extractionGot 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; 
} 

मैं ग्लाइड उपयोग कर रहा हूँ ver 3.7

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

यहाँ काम कर रहे उदाहरण भरा है: https://github.com/nieldeokar/GlideApp

3

आपने उल्लेख किया है के रूप में, Log.d (टीएजी, "निकासी शुरू करने के लिए के बारे में") कभी नहीं ट्रिगर हो जाता है, जिसका अर्थ है रिसोर्स रीडी कभी नहीं बुलाया जाता है। यह कुछ त्रुटि के कारण हो सकता है। त्रुटि कॉलबैक ओवरराइड करने का प्रयास करें।

समस्या की पहचान करने के लिए मैं आपको समस्या को डीबग करने के लिए सरल लक्ष्य के अन्य कॉलबैक को ओवरराइड करने की सलाह दूंगा।

@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 
    } 
संबंधित मुद्दे