Làm thế nào để một người sử dụng lướt để tải hình ảnh vào bitmap?


141

Tải xuống một URL ImageViewrất dễ dàng bằng cách sử dụng Glide:

Glide
   .with(context)
   .load(getIntent().getData())
   .placeholder(R.drawable.ic_loading)
   .centerCrop()
   .into(imageView);

Tôi đang tự hỏi nếu tôi có thể tải xuống Bitmapnhư là một ? Tôi muốn tải xuống một bitmap thô mà sau đó tôi có thể thao tác bằng các công cụ khác. Tôi đã xem qua mã và không thấy cách làm.

Câu trả lời:


175

Hãy chắc chắn rằng bạn đang ở phiên bản mới nhất

implementation 'com.github.bumptech.glide:glide:4.10.0'

Kotlin:

Glide.with(this)
        .asBitmap()
        .load(imagePath)
        .into(object : CustomTarget<Bitmap>(){
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                imageView.setImageBitmap(resource)
            }
            override fun onLoadCleared(placeholder: Drawable?) {
                // this is called when imageView is cleared on lifecycle call or for
                // some other reason.
                // if you are referencing the bitmap somewhere else too other than this imageView
                // clear it here as you can no longer have the bitmap
            }
        })

Kích thước bitmap:

nếu bạn muốn sử dụng kích thước ban đầu của hình ảnh, hãy sử dụng hàm tạo mặc định như trên, nếu không, bạn có thể chuyển kích thước mong muốn của mình cho bitmap

into(object : CustomTarget<Bitmap>(1980, 1080)

Java:

Glide.with(this)
        .asBitmap()
        .load(path)
        .into(new CustomTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }

            @Override
            public void onLoadCleared(@Nullable Drawable placeholder) {
            }
        });

Câu trả lời cũ:

Với compile 'com.github.bumptech.glide:glide:4.8.0'và dưới

Glide.with(this)
        .asBitmap()
        .load(path)
        .into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }
        });

Cho compile 'com.github.bumptech.glide:glide:3.7.0'và dưới

Glide.with(this)
        .load(path)
        .asBitmap()
        .into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                imageView.setImageBitmap(resource);
            }
        });

Bây giờ bạn có thể thấy một cảnh báo SimpleTarget is deprecated

Lý do:

Điểm chính của việc phản đối SimpleTarget là cảnh báo bạn về những cách mà nó cám dỗ bạn phá vỡ hợp đồng API của Glide. Cụ thể, nó không làm gì để buộc bạn ngừng sử dụng bất kỳ tài nguyên nào bạn đã tải sau khi SimpleTarget bị xóa, điều này có thể dẫn đến sự cố và hỏng đồ họa.

Ảnh SimpleTargettĩnh vẫn có thể được sử dụng miễn là bạn đảm bảo rằng bạn không sử dụng bitmap sau khi imageView bị xóa.


10
Tôi đang sử dụng Glide 4.0 và dường như không thể tìm thấy .asBitmap ()
Chris Nevill

8
Đối với các cuộc gọi đồng bộ, hãy sử dụng Glide.with (this) .asBitmap (). Load (imageUrl) .submit (100, 100) .get (). Nó có thể hữu ích khi bạn muốn thêm biểu tượng trong thông báo thông qua .setLargeIcon (bitmap)
Yazon2006

1
@Max công việc này là dành cho tôi khi triển khai 'com.github.bumptech.glide: glide: 3.6.1'
Bipin Bharti

2
@Nux đảm bảo bạn đang ở phiên bản mới nhất4.9.0
Tối đa

1
.asBitmap()nên được đặt sau with(this)nếu nó chưa được giải quyết.
Alston

177

Tôi không đủ quen thuộc với Glide, nhưng có vẻ như nếu bạn biết kích thước mục tiêu, bạn có thể sử dụng một cái gì đó như thế này:

Bitmap theBitmap = Glide.
        with(this).
        load("http://....").
        asBitmap().
        into(100, 100). // Width and height
        get();

Có vẻ như bạn có thể vượt qua -1,-1 và có được một hình ảnh kích thước đầy đủ (hoàn toàn dựa trên các bài kiểm tra, không thể thấy nó được ghi lại).

Lưu ý into(int,int)trả về a FutureTarget<Bitmap>, vì vậy bạn phải bọc nó trong một khối thử bắt ExecutionExceptionInterruptedException. Đây là một ví dụ đầy đủ hơn về thực thi, đã thử nghiệm và hoạt động:

class SomeActivity extends Activity {

    private Bitmap theBitmap = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // onCreate stuff ...
        final ImageView image = (ImageView) findViewById(R.id.imageView);

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Looper.prepare();
                try {
                    theBitmap = Glide.
                        with(SomeActivity.this).
                        load("https://www.google.es/images/srpr/logo11w.png").
                        asBitmap().
                        into(-1,-1).
                        get();
                 } catch (final ExecutionException e) {
                     Log.e(TAG, e.getMessage());
                 } catch (final InterruptedException e) {
                     Log.e(TAG, e.getMessage());
                 }
                 return null;
            }
            @Override
            protected void onPostExecute(Void dummy) {
                if (null != theBitmap) {
                    // The full bitmap should be available here
                    image.setImageBitmap(theBitmap);
                    Log.d(TAG, "Image loaded");
                };
            }
        }.execute();
    }
}

Theo đề xuất của Monkeyless trong bình luận bên dưới (và đây dường như cũng là cách chính thức ), bạn có thể sử dụng một SimpleTarget, tùy ý kết hợp với override(int,int)để đơn giản hóa đáng kể mã. Tuy nhiên, trong trường hợp này phải cung cấp kích thước chính xác (mọi thứ dưới 1 không được chấp nhận):

Glide
    .with(getApplicationContext())
    .load("https://www.google.es/images/srpr/logo11w.png")
    .asBitmap()
    .into(new SimpleTarget<Bitmap>(100,100) {
        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
            image.setImageBitmap(resource); // Possibly runOnUiThread()
        }
    });

như được đề xuất bởi @hennry nếu bạn yêu cầu cùng một hình ảnh thì hãy sử dụngnew SimpleTarget<Bitmap>()


4
Đối với hậu thế, bạn không cần tác vụ không đồng bộ, chỉ cần sử dụng .override (int, int) và / hoặc SimpleTarget
Sam Judd

2
@Monkeyless cảm ơn, tôi đã mở rộng câu trả lời của mình để bao gồm đề xuất của bạn.
outlyer

33
Nếu bạn muốn đạt được một bitmap ở kích thước ban đầu, tốt hơn hết là vượt qua Target.SIZE_ORIGINALcả chiều rộng và chiều cao của bitmap thay vì -1
Alex Bonel

5
Bạn sẽ nhận được bitmap kích thước đầy đủ nếu bạn không cung cấp bất kỳ tham số nào SimpleTargetnhư thế này:new SimpleTarget<Bitmap>(){....}
Henry

3
Trong Glide 4.0.0+, hãy sử dụng .asBitmap () trước.load () và .submit (100, 100) thay vì .into (100, 100)
Yazon2006

16

Có vẻ như ghi đè Targetlớp hoặc một trong các triển khai như BitmapImageViewTargetvà ghi đè setResourcephương thức để chụp bitmap có thể là cách để đi ...

Điều này chưa được kiểm tra. :-)

    Glide.with(context)
         .load("http://goo.gl/h8qOq7")
         .asBitmap()
         .into(new BitmapImageViewTarget(imageView) {
                     @Override
                     protected void setResource(Bitmap resource) {
                         // Do bitmap magic here
                         super.setResource(resource);
                     }
         });

3
Bitmap sẽ không chiếm chiều rộng / chiều cao của imageView? Tôi hy vọng sẽ có được Bitmap không thay đổi ban đầu.
JohnnyLambada

Đối với Glide 4.0.0+, hãy sử dụng .asBitmap () trước.load ()
Saeed

10

CẬP NHẬT

Bây giờ chúng ta cần sử dụng Custom Targets

MẪU MÃ

    Glide.with(mContext)
            .asBitmap()
            .load("url")
            .into(new CustomTarget<Bitmap>() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {

                }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {
                }
            });

Làm thế nào để một người sử dụng lướt để tải hình ảnh vào bitmap?

Tất cả các câu trả lời trên là đúng nhưng lỗi thời

bởi vì trong phiên bản mới của Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

Bạn sẽ tìm thấy lỗi dưới đây trong mã

  • Các .asBitmap()không có sẵn trongglide:4.8.0

nhập mô tả hình ảnh ở đây

  • SimpleTarget<Bitmap> không được chấp nhận

nhập mô tả hình ảnh ở đây

Đây là giải pháp

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;



public class MainActivity extends AppCompatActivity {

    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.imageView);

        Glide.with(this)
                .load("")
                .apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
                .into(new Target<Drawable>() {
                    @Override
                    public void onLoadStarted(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {

                    }

                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {

                        Bitmap bitmap = drawableToBitmap(resource);
                        imageView.setImageBitmap(bitmap);
                        // now you can use bitmap as per your requirement
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void getSize(@NonNull SizeReadyCallback cb) {

                    }

                    @Override
                    public void removeCallback(@NonNull SizeReadyCallback cb) {

                    }

                    @Override
                    public void setRequest(@Nullable Request request) {

                    }

                    @Nullable
                    @Override
                    public Request getRequest() {
                        return null;
                    }

                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onStop() {

                    }

                    @Override
                    public void onDestroy() {

                    }
                });

    }

    public static Bitmap drawableToBitmap(Drawable drawable) {

        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        int width = drawable.getIntrinsicWidth();
        width = width > 0 ? width : 1;
        int height = drawable.getIntrinsicHeight();
        height = height > 0 ? height : 1;

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }
}

Nếu bạn thử asBItmap trước .load để nó không gây ra lỗi cho bạn
Vipul Chauhan

@Spritzig vấn đề bạn đang gặp phải bây giờ
Nilesh Rathod

@NileshRathod Nó không hiển thị cho tôi biểu tượng không có lỗi gì mà chỉ không hiển thị biểu tượng.
nideba

@NileshRathod Bạn đã tìm thấy vấn đề cho việc này chưa?
nideba

7

Đây là những gì làm việc cho tôi: https://github.com/bumptech/glide/wiki/Custom-target#overriding-default-behavior

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.transition.Transition;
import com.bumptech.glide.request.target.BitmapImageViewTarget;

...

Glide.with(yourFragment)
  .load("yourUrl")
  .asBitmap()
  .into(new BitmapImageViewTarget(yourImageView) {
    @Override
    public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> anim) {
        super.onResourceReady(bitmap, anim);
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {  
            @Override
            public void onGenerated(Palette palette) {
                // Here's your generated palette
                Palette.Swatch swatch = palette.getDarkVibrantSwatch();
                int color = palette.getDarkVibrantColor(swatch.getTitleTextColor());
            }
        });
    }
});

4

Nếu bạn muốn gán hình ảnh bitmap động cho các biến bitmap

Ví dụ như kotlin

backgroundImage = Glide.with(applicationContext).asBitmap().load(PresignedUrl().getUrl(items!![position].img)).into(100, 100).get();

Các câu trả lời trên không làm việc cho tôi

.asBitmap nên trước .load("http://....")


4
.into (100, 100) không được sử dụng .submit (100, 100)
Yazon2006

Tại sao các f không lướt qua những thứ như thế này? thực tế nó cũng giống như cách sử dụng ...
kkarakk

2

CẬP NHẬT CHO PHIÊN BẢN MỚI

Glide.with(context.applicationContext)
    .load(url)
    .listener(object : RequestListener<Drawable> {
        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>?,
            isFirstResource: Boolean
        ): Boolean {
            listener?.onLoadFailed(e)
            return false
        }

        override fun onResourceReady(
            resource: Drawable?,
            model: Any?,
            target: com.bumptech.glide.request.target.Target<Drawable>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            listener?.onLoadSuccess(resource)
            return false
        }

    })
    .into(this)

TRẢ LỜI

Câu trả lời của @ outlyer là đúng, nhưng có một số thay đổi trong phiên bản Glide mới

Phiên bản của tôi: 4.7.1

Mã số:

 Glide.with(context.applicationContext)
                .asBitmap()
                .load(iconUrl)
                .into(object : SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
                    override fun onResourceReady(resource: Bitmap, transition: com.bumptech.glide.request.transition.Transition<in Bitmap>?) {
                        callback.onReady(createMarkerIcon(resource, iconId))
                    }
                })

Lưu ý: mã này chạy trong UI Thread, do đó bạn có thể sử dụng AsyncTask, Executor hoặc đôi khi khác để đồng thời (như mã @ outlyer'ser) Nếu bạn muốn lấy kích thước ban đầu, hãy đặt Target.SIZE_ORIGINA làm mã của tôi. Không sử dụng -1, -1


4
SimpleTarget <Bitmap> không được dùng nữa trong phiên bản mới
Nainal

-1

Phiên bản mới hơn:

GlideApp.with(imageView)
    .asBitmap()
    .override(200, 200)
    .centerCrop()
    .load(mUrl)
    .error(R.drawable.defaultavatar)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .signature(ObjectKey(System.currentTimeMillis() / (1000*60*60*24))) //refresh avatar cache every day
    .into(object : CustomTarget<Bitmap>(){
        override fun onLoadCleared(placeholder: Drawable?) {}
        override fun onLoadFailed(errorDrawable: Drawable?) {
            //add context null check in case the user left the fragment when the callback returns
            context?.let { imageView.addImage(BitmapFactory.decodeResource(resources, R.drawable.defaultavatar)) }
        }
        override fun onResourceReady(
            resource: Bitmap,
            transition: Transition<in Bitmap>?) { context?.let { imageView.addImage(resource) } }
    })
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.