Android: как я могу добавить водяной знак на несколько изображений, используя Пикассо и цели - PullRequest
0 голосов
/ 28 октября 2019

У меня есть приложение, которое загружает изображения с сервера, добавляет водяной знак, а затем позволяет пользователю обмениваться ими через другие приложения. Я использую Picasso для загрузки изображений в мишени.

Проблема в том, что загрузка изображений в мишени занимает немного времени, поэтому мне нужно найти способ дождаться завершения процесса. Я читал о CompletableFuture, но он нацелен только на Android +24, и это недопустимо.

Вот что я сделал до сих пор

//Global var
final List<Target> remoteImgTargets = new ArrayList<>();

//method
List<ImageToShare> remoteImages = new ArrayList<>();
final ArrayList<Uri> finishedImages = new ArrayList<>();

int countImages = remoteImages.size();
for (int i = 0; i < countImages; i++) {
            final int k=i;
            Target target = new Target() {

                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

                    remoteImgTargets.remove(this);

                    //Add watermark here
                    finishedImages.add(Utils.getLocalBitmapUri(watermakedBmp, context));
                    Log.e("Targets", "Loaded: " + k);
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                    remoteImgTargets.remove(this);
                    Log.e("Targets", "onBitmapFailed(): ");
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                    Log.e("Targets", "Preparing: " + k);
                }
            };
            remoteImgTargets.add(target);
            Picasso.with(context)
                    .load(remoteImages.get(k).getImageurl()) // Start loading the current target
                    .into(target);

        }

Далее я использую RxAndroid для наблюдения за процессом и обработки

ArrayList<Uri> globalUriArray = new ArrayList<>();
Observable<Uri> observable2 = Observable
                .fromIterable(finishedImages)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

        Observer<Uri> observer = new Observer<Uri>() {
            @Override
            public void onSubscribe(Disposable d) {
                //TODO
            }

            @Override
            public void onNext(Uri uri) {
                globalUriArray.add(uri);
            }

            @Override
            public void onError(Throwable e) {
                //TODO
            }

            @Override
            public void onComplete() {
                if(globalUriArray.size()>0) {
                    //Display share intent
                }
            }
        };

        observable2.subscribe(observer);

* Проблема * Целевая загрузка остается позади, и загружается лишь небольшая часть изображений.

Требуется помощь Как ждать, пока цели Пикассо завершат загрузку и, возможно, ответный огонь, если это возможно, или что-нибудь.

Заранее спасибо ...

1 Ответ

0 голосов
/ 13 ноября 2019

Проблема здесь в том, что вы не синхронизируете все , что я имею в виду, когда вы загружаете изображения в отдельный поток, добавляете водяной знак и, наконец, вызываете все эти Rx в потоке планировщика и загружаетеизображений происходит в совершенно другом главном потоке,

, поэтому вам придется синхронизировать все извлекаемые изображения и добавлять водяные знаки в потоке планировщика и загружать изображения в основной поток, найдите приведенный ниже пример. Я сделал это общим, чтобы дать представление о том, как это должно быть сделано.

 private void loadImageObserver(final String url) {
        Observable.create(new ObservableOnSubscribe<Bitmap>() {
            @Override
            public void subscribe(final ObservableEmitter<Bitmap> emitter) {
                //Use any-way to download bitmap from url
                //here Picasso is used to download the bitmap as was the question 

                try {
                    Bitmap bitmap = Picasso.get()
                            .load(url) // Start loading the current target
                            .get();
                    if (bitmap != null) {
                        emitter.onNext(bitmap);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    emitter.onError(e);
                }


            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "subscribed");
                    }

                    @Override
                    public void onNext(Bitmap bitmap) {
                        Log.d(TAG, "on next " + bitmap.getWidth() + " " + bitmap.getHeight() + " " + bitmap.getByteCount());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "error " + e.getLocalizedMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "on complete");
                    }
                });
    }
...