LuckSiege / LuckSiege/PictureSelector

在setAddBitmapWatermarkListener内异步处理水印导致的某些机型 图片异常或者丢失

Open
#2,854 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
13.6k
Forks
3.1k
PR merge metrics
No merged PRs in 30d

Description

Current use version?

当前使用的版本是多少?

v3.11.2

Will this problem occur in demo?

Demo能否复现这问题?

可以在某些配置低或者平板上可以复现

Describe the problem or provide an error log?

描述问题或提供错误log?

setAddBitmapWatermarkListener api 如果使用异步处理并使用onCallback回调的时候,
虽然从日志来看是按顺序处理并最后调用dispatchWatermarkResult的,但是保存的水印图片会存在保存不完整或者丢失。
如果在直接写水印代码,不使用异步处理,是正常的,但是会导致loading dialog 被卡住。

使用了kotlin协程的普通的线程工具类都会出现

调用代码 1

.setAddBitmapWatermarkListener { context, srcPath, _, call ->
                val path = if (srcPath.startsWith("content://")) {
                    NovaFile.getPathByUri(context, Uri.parse(srcPath))
                } else {
                    srcPath
                }
                GlobalIOScope.launch {
                    val copyUrl = copyFileToNova(albumKey, path)
                    val dateTime = path2Date(path)
                    signWatermark(copyUrl, location, nickName, dateTime)
                    withContext(Dispatchers.Main){
                        call.onCallback(srcPath, copyUrl)
                    }
                }
            }

调用代码2

.setAddBitmapWatermarkListener { context, srcPath, _, call ->
                ThreadUtils.executeByIo(object : SimpleTask<String>() {
                    override fun doInBackground(): String {
                        val path = if (srcPath.startsWith("content://")) {
                            NovaFile.getPathByUri(context, Uri.parse(srcPath))
                        } else {
                            srcPath
                        }
                        val copyUrl = copyFileToNova(albumKey, path)
                        val dateTime = path2Date(path)
                        signWatermark(copyUrl, location, nickName, dateTime)
                    }

                    override fun onSuccess(copyUrl: String?) {
                        call.onCallback(srcPath, copyUrl)
                    }
                })
}

尝试修改addBitmapWatermark的代码,直接让这部分运行在 PictureThreadUtils 的线程里可以正常工作,但是估计违背api涉及初衷。

PictureThreadUtils.executeByIo(new PictureThreadUtils.SimpleTask<ArrayList<LocalMedia>>() {
            @Override
            public ArrayList<LocalMedia> doInBackground() {
                for (LocalMedia localMedia : result) {
                    selectorConfig.onBitmapWatermarkListener.onAddBitmapWatermark(
                            getAppContext(),
                            localMedia.getAvailablePath(),
                            localMedia.getMimeType(),
                            (srcPath, resultPath) -> {
                                if (TextUtils.isEmpty(srcPath)) {
                                    dispatchWatermarkResult(result);
                                } else {
                                    localMedia.setWatermarkPath(resultPath);
                                }
                            }
                    );
                }
                return result;
            }

            @Override
            public void onSuccess(ArrayList<LocalMedia> result) {
                PictureThreadUtils.cancel(this);
                dispatchWatermarkResult(result);
            }
        });

视频内有两张图片的颜色是不对的,其他更严重的情况是有时候图片只有一半或者直接丢失。

https://github.com/LuckSiege/PictureSelector/assets/13929310/c89f04b9-0ae6-4d7b-8ed7-7f76a0d1acb9

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at setAddBitmapWatermarkListener and the addBitmapWatermark flow shown in the report, then trace dispatchWatermarkResult and the PictureThreadUtils variant. Reproduce the incomplete, missing, or incorrectly colored images on a low-end device or tablet using asynchronous callbacks. Done means asynchronous watermark processing preserves every image and dispatches the complete result reliably.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java, kotlin
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.