2014-07-10 17 views
10

Tôi có một phương thức tải hình ảnh, nếu hình ảnh chưa được tải trước khi nó sẽ tìm kiếm trên máy chủ. Sau đó, nó lưu trữ nó trong hệ thống tập tin ứng dụng. Nếu nó nằm trong hệ thống tệp, nó sẽ tải hình ảnh đó thay vì nó nhanh hơn nhiều so với việc kéo hình ảnh từ máy chủ. Nếu bạn đã tải hình ảnh trước đó mà không đóng ứng dụng, nó sẽ được lưu trữ trong một từ điển tĩnh để nó có thể được tải lại mà không cần sử dụng nhiều bộ nhớ hơn, để tránh lỗi bộ nhớ.Nhận bitmap từ ImageView được tải bằng Picasso

Tất cả đều hoạt động tốt cho đến khi tôi bắt đầu sử dụng thư viện tải hình ảnh Picasso. Bây giờ tôi đang tải hình ảnh vào một ImageView nhưng tôi không biết làm thế nào để có được Bitmap được trả về để tôi có thể lưu trữ nó trong một tập tin hoặc từ điển tĩnh. Điều này khiến mọi việc trở nên khó khăn hơn. bởi vì nó có nghĩa là nó cố gắng tải hình ảnh từ máy chủ mỗi lần, đó là điều tôi không muốn xảy ra. Có cách nào tôi có thể nhận được Bitmap sau khi tải nó vào ImageView? Dưới đây là mã của tôi:

public Drawable loadImageFromWebOperations(String url, 
     final String imagePath, ImageView theView, Picasso picasso) { 
    try { 
     if (Global.couponBitmaps.get(imagePath) != null) { 
      scaledHeight = Global.couponBitmaps.get(imagePath).getHeight(); 
      return new BitmapDrawable(getResources(), 
        Global.couponBitmaps.get(imagePath)); 
     } 
     File f = new File(getBaseContext().getFilesDir().getPath() 
       .toString() 
       + "/" + imagePath + ".png"); 

     if (f.exists()) { 
      picasso.load(f).into(theView); 
      **This line below was my attempt at retrieving the bitmap however 
      it threw a null pointer exception, I assume this is because it 
      takes a while for Picasso to add the image to the ImageView** 
      Bitmap bitmap = ((BitmapDrawable)theView.getDrawable()).getBitmap(); 
      Global.couponBitmaps.put(imagePath, bitmap); 
      return null; 
     } else { 
      picasso.load(url).into(theView); 
      return null; 
     } 
    } catch (OutOfMemoryError e) { 
     Log.d("Error", "Out of Memory Exception"); 
     e.printStackTrace(); 
     return getResources().getDrawable(R.drawable.default1); 
    } catch (NullPointerException e) { 
     Log.d("Error", "Null Pointer Exception"); 
     e.printStackTrace(); 
     return getResources().getDrawable(R.drawable.default1); 
    } 
} 

Bất kỳ trợ giúp nào sẽ được đánh giá cao, cảm ơn bạn!

+0

Picasso sẽ không tải hình ảnh từ Máy chủ mỗi lần. Chỉ vào lần đầu tiên sau đó nó tải từ thư mục bộ nhớ cache. – intrepidkarthi

Trả lời

7

Picasso cho phép bạn kiểm soát trực tiếp các hình ảnh đã tải xuống. Để lưu hình ảnh đã tải về vào tập tin làm điều gì đó như thế này:

Picasso.with(this) 
    .load(currentUrl) 
    .into(saveFileTarget); 

đâu:

saveFileTarget = new Target() { 
    @Override 
    public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from){ 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + FILEPATH); 
       try { 
        file.createNewFile(); 
        FileOutputStream ostream = new FileOutputStream(file); 
        bitmap.compress(CompressFormat.JPEG, 75, ostream); 
        ostream.close(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 
} 
+0

Điều này cũng có thể được thực hiện với một Drawable? (mà Im cố gắng tp nối thêm vào một EditText) Tôi không nhận được bất kỳ lỗi nào nhưng nó không hoạt động – Sauron

0

Vì bạn đang sử dụng Picasso, bạn có thể cũng muốn tận dụng tối đa nó. Nó bao gồm một cơ chế bộ nhớ đệm mạnh mẽ.

Sử dụng picasso.setDebugging(true) trên Picasso trường hợp của bạn để xem loại bộ nhớ đệm nào xảy ra (hình ảnh được tải từ đĩa, bộ nhớ hoặc mạng). Xem: http://square.github.io/picasso/ (chỉ số debug)

Các trường hợp mặc định của Picasso được cấu hình với (http://square.github.io/picasso/javadoc/com/squareup/picasso/Picasso.html#with-android.content.Context-)

LRU bộ nhớ cache của 15% các ứng dụng có sẵn RAM

Disk cache 2% không gian lưu trữ lên đến 50MB nhưng không nhỏ hơn 5MB. (Lưu ý: đây là chỉ có sẵn trên API 14 + hoặc nếu bạn đang sử dụng một thư viện độc lập cung cấp một bộ nhớ cache đĩa trên tất cả các cấp độ API như OkHttp)

Bạn cũng có thể chỉ định Cache dụ bạn sử dụng Picasso.Builder để tùy chỉnh dụ của bạn và bạn có thể chỉ định Downloader để kiểm soát tốt hơn. (Có một triển khai thực hiện OkDownloader trong Picasso được sử dụng tự động nếu bạn bao gồm OkHttp trong ứng dụng của mình.)

34

Với Picasso bạn không cần phải thực hiện từ điển tĩnh của riêng bạn bởi vì nó được thực hiện tự động cho bạn. @intrepidkarthi đúng theo nghĩa là các hình ảnh được Picasso tự động lưu vào bộ nhớ cache lần đầu tiên chúng được tải và do đó nó không liên tục gọi máy chủ để có được cùng một hình ảnh.

Điều đó đang được nói, tôi thấy mình trong tình huống tương tự: Tôi cần truy cập vào bitmap đã được tải xuống để lưu trữ nó ở một nơi khác trong ứng dụng của tôi. Đối với điều đó, tôi đã chỉnh sửa câu trả lời của @Gilad Haimov một chút:

Picasso.with(this) 
     .load(url) 
     .into(new Target() { 
      @Override 
      public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from) { 
       /* Save the bitmap or do something with it here */ 

       //Set it in the ImageView 
       theView.setImageBitmap(bitmap); 
      } 

      @Override 
      public void onPrepareLoad(Drawable placeHolderDrawable) {} 

      @Override 
      public void onBitmapFailed(Drawable errorDrawable) {} 
    }); 

Điều này cho phép bạn truy cập vào bitmap đã tải trong khi vẫn tải nó một cách không đồng bộ.Bạn chỉ cần nhớ đặt nó trong ImageView vì nó không còn tự động làm cho bạn nữa.

Lưu ý phụ, nếu bạn quan tâm đến việc biết hình ảnh của bạn đến từ đâu, bạn có thể truy cập thông tin đó trong cùng một phương pháp. Đối số thứ hai của phương thức trên, Picasso.LoadedFrom from, là một enum cho phép bạn biết nguồn bitmap được tải từ nguồn nào (ba nguồn là DISK, MEMORYNETWORK. (Source). Square Inc. cũng cung cấp cách trực quan nhìn thấy nơi bitmap đã được nạp từ bằng cách sử dụng các chỉ số debug giải thích here.

Hope this helps!

-1

sử dụng này

Picasso.with(context) 
.load(url) 
.into(imageView new Callback() { 
    @Override 
    public void onSuccess() { 
     //use your bitmap or something 
    } 

    @Override 
    public void onError() { 

    } 
}); 

Hy vọng nó sẽ giúp bạn

+2

'onSuccess()' không cung cấp đối tượng Bitmap. – Hemanth

+0

Hemanth chỉ chuyển đổi hoặc sử dụng Target. Target cung cấp bitmap! – Madi

0

Trong ví dụ này, tôi sử dụng để thiết lập nền của một thanh công cụ colapsing.

public class MainActivity extends AppCompatActivity { 

CollapsingToolbarLayout colapsingToolbar; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    colapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.colapsingToolbar); 
    ImageView imageView = new ImageView(this); 
    String url ="www.yourimageurl.com" 


    Picasso.with(this) 
     .load(url) 
     .resize(80, 80) 
     .centerCrop() 
     .into(image); 

    colapsingToolbar.setBackground(imageView.getDrawable()); 

} 

Tôi hy vọng nó sẽ giúp bạn.

Các vấn đề liên quan